Skip to content

cards-ios-demo - Managed via CloudFormation

Notifications You must be signed in to change notification settings

pomelo-la/cards-ios-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PomeloCards iOS SDK

cover

Swift Platforms CocoaPods Compatible Swift Package Manager

The PomeloCards iOS SDK makes it easy to build a card flows experience in your iOS App. This module provides powerfull customizable UI screens and flows that can be used by any client app to offer a complete cards flow to your customers.

Table of Content


System Requirements

  • iOS 13+
  • Xcode 11+
  • Swift 5.1+

Adding Cards

We support Cocoapods and Swift Package Manager. If you link the library manually, use a version from our releases page.

1. Import Dependency

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.

To add the SDK in your project you just have to follow these steps:

  1. In Xcode, select File > Swift Packages > Add Package Dependency and enter https://github.com/pomelo-la/cards-ios.git as the repository URL.

  2. Select the latest version number from our releases page.

  3. Add the PomeloCards product to the target of your app.

If you want to add the SDK as a dependency on your swift package follow the next steps:

Once you have your Swift package set up, adding PomeloCards as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "git@github.com:pomelo-la/cards-ios.git", .upToNextMajor(from: "0.1.0"))
]

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.


CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website.

To integrate PomeloCards into your Xcode project using CocoaPods you just have to:

  1. If you haven’t already, install the latest version of Cocoapods.

  2. Add our private spec repository to your CI/Local environment:

pod repo add pomelo-specs 'https://github.com/pomelo/Specs.git'
  1. If you don’t have an existing Podfile, run the following command to create one:
pod init
  1. Add our repo source at the top of your Podfile:
source 'https://github.com/pomelo/Specs.git'
  1. Last, just add the dependency to your app’s target.
target 'MyApp' do
  pod 'PomeloCards', '~> 0.1.0'
end
  1. Don’t forget to use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file, from here on out.

We recommend to use the opstimistic operator '~>' instead of not specify the version your going to use, to be sure that you are not going to update the version of our SDK to one that have a breaking change without testing it firts.


2. Register SDK into your Application

To initialize the SDK, first you have to setup the initial configuration on your SceneDelegate.

let configuration = PomeloCardsConfiguration(environment: .development)

PomeloCards.initialize(with: configuration)
Parameters
Environment: enum Indicates the environment, which can be .development, staging or production

You also have to setup the NSFaceIDUsageDescription parametter on your Info.plist. This is because we use the biometric prompt to be sure that the end users is actually the cardHolder.

Example:

<key>NSFaceIDUsageDescription</key>
<string>$(PRODUCT_NAME) uses Face ID to validate your identity</string>

Screen Shot 2022-12-22 at 14 04 03

You can use the message of your preference


3. Authorization

Any company involved with the processing, transmission, or storage of card data, incluiding the primary account number (PAN), expiration date, and card verification value (CVV), must comply with the Payment Card Industry Data Security Standard (PCI DSS). Achieving PCI DSS certification is both time consuming and expensive.

Pomelo is fully PCI-Service Provider compliant and handles the unencrypted sensitive card data for you. Your servers never store, transmit, or process the card data.

The following process describes how Pomelo components work using the authorization service layer provided by your application to ensure that your end users have their sensitive data in a securely way.

DOCs - Guideline de Diseño _ UX

Because of that you have to configure an authorization service injecting an AuthorizationService that implements the protocol PomeloAuthorizationServiceProtocol. On it you have to implement the logic to generate an end user token which is a short-lived JWT token that you have to provide to the SDK to be able to communicate with our secure data services.

We reccomend to encapsulate the logic of the end user token request on your back end services and only make a fetch to that service in your iOS native implementation of the AuthorizationService. For more information about the end user token, examples, and recomendations for backend implementation for it, please visit this page.

Once you have your AuthorizationService fully developed you just have to configure it on your SceneDelegate:

PomeloNetworkConfigurator.shared.configure(authorizationService: EndUserTokenAuthorizationService())

Go to this repo to see an example of an authorization service implemented on our demo app.


Fully setup sample

Having followed all the previous steps your SceneDelegateconfiguration must be like:

import UIKit
import PomeloCards
import PomeloUI
import PomeloNetworking

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        setupPomeloCards()
    }

    private func setupPomeloCards() {
        //Configure Cards SDK
        PomeloCards.initialize(with: PomeloCardsConfiguration(environment: .develop))
        //Configure authorization service on PomeloNetworkConfigurator
        PomeloNetworkConfigurator.shared.configure(authorizationService: EndUserTokenAuthorizationService())
        //Configure theme on PomeloUI
        PomeloUIGateway.shared.configure(theme: YourTheme())
    }
}

See the customizing section for more information about how to build your YourTheme to customize the UI copmponents.


4. Usage

To use the SDK components and methos all you have to do is to add the import and you are ready to go.

import PomeloCards

// Put your implementation here!

Initializing Widgets

Card

Card image with sensitive data

class PomeloCardWidgetView: UIView

Summary

Public function
init
init(
    cardholderName: String,
    lastFourCardDigits: String,
    imageFetcher: PomeloUIImageFetchable,
    copyButtonIcon: UIImage? = UIImage(systemName: "doc.on.doc"),
    fontTextColor: UIColor? = nil,
    parentViewController: UIViewController? = nil
    )

Initialize the widget with its content.

Parameters
cardholderName: String Card holder name. It will be shown as upper case.
lastFourCardDigits: String The last four digits of the card to be shown
imageFetcher: UIImage? (Optional) The background card image. The background is clear by default.
copyButtonIcon: UIImage? The copy data icon
fontTextColor: UIColor? (optional) the color of the font. You can select the font color but if you dont, the font its going to be white with dark background or black with lighter background automatically
parentViewController: UIVIewController? (Optional) The parent view controller that contains the cardView. If it is provided it will be used to display an alert with retry logic in case the service fails.
showSensitiveData
func showSensitiveData(
    cardId: String, 
    onPanCopy: (() -> Void)?, 
    completionHandler: @escaping (Result<Void, PomeloError>) -> Void
    )

Reveals the hidden sensitive data from the card after passing successfully a biometric prompt.

Parameters
cardId: String The id of the card. Example _crd-ABCD1234_e
onPanCopy: (() -> Void)? Callback called when the user copied the card PAN number to the Pasteboard. It can be used to show an alert on your app
completionHandler: @escaping (Result<Void, PomeloError>) -> Void Callback called after Pomelo services request, it returns an error in case of fauilure, otherwise it succeded.

Card List Information

List with sensitive data from the card.

class PomeloCardWidgetDetailViewController

Summary

Public function

You can display the card informations as a list and embed in your view just using the ViewController initializer as follows:

let widgetDetailViewController = PomeloCardWidgetDetailViewController()

Also can display the list as a bottomsheet using the extension displayViewControllerAsBottomSheet from your parent view controller:

let widgetDetailViewController = PomeloCardWidgetDetailViewController()

yourParentViewController.displayViewControllerAsBottomSheet(widgetDetailViewController)
showSensitiveData
func showSensitiveData(
    cardId: String, 
    onPanCopy: (() -> Void)?, 
    completionHandler: @escaping (Result<Void, PomeloError>) -> Void
    )

Reveals the hidden sensitive data from the card after passing successfully a biometric prompt.

Parameters
cardId: String The id of the card. Example _crd-ABCD1234_e
onPanCopy: (() -> Void)? Callback called when the user copied the card PAN number to the Pasteboard. It can be used to show an alert on your app
completionHandler: @escaping (Result<Void, PomeloError>) -> Void Callback called after Pomelo services request, it returns an error in case of fauilure, otherwise it succeded.

Activate Card

Activates a new card after completing the PAN and PIN.

Summary

Public function
init
init(completionHandler: @escaping (Result<String?, PomeloError>) -> Void)

Initialize the widget with its content.

Parameters
completionHandler: @escaping (Result<String?, PomeloError>) -> Void Callback called after the activation, it returns the card id if succeeded or an error in case of failure.

Change PIN

Updates the PIN number.

Summary

Public function
init
init(
    cardId: String, 
    completionHandler: @escaping (Result<Void, PomeloError>) -> Void
    )   

Initialize the widget with its content.

Parameters
cardId: String The id of the card to activate
completionHandler: @escaping (Result<Void, PomeloError>) -> Void Callback called after the change pin request, it returns an error in case of failure otherwise it succeded

Customizing

You can customize the appearance of the UI components by using the PomeloTheme object. This object allows you to change colors, button styles, fonts, feedback icons and cards background images.

We show you a custom PomeloTheme bellow:

class YourTheme: PomeloThemeable {
    var colors: PomeloColors = PomeloColors(primary: .primaryColor,
                                            secondary: .secondaryColor,
                                            background: .backgroundColor)
    
    var buttons: PomeloButtonsStyle = PomeloButtonsStyle(
        primary: .init(
            cornerRadius: 10,
            enabledStyle: .init(backgroundColor: .primaryColor, foregroundColor: .white),
            disabledStyle: .init(backgroundColor: .systemGray6, foregroundColor: .systemGray3)
        ),
        secondary: .init(
            cornerRadius: 10,
            enabledStyle: .init(backgroundColor: .secondaryColor, foregroundColor: .primaryColor),
            disabledStyle: .init(backgroundColor: .systemGray6, foregroundColor: .systemGray3)
        ),
        tertiary: .init(
            cornerRadius: 10,
            enabledStyle: .init(backgroundColor: .clear, foregroundColor: .primaryColor),
            disabledStyle: .init(backgroundColor: .clear, foregroundColor: .systemGray3)
        ),
        link: .init(
            cornerRadius: 10,
            enabledStyle: .init(backgroundColor: .clear, foregroundColor: .primaryColor),
            disabledStyle: .init(backgroundColor: .clear, foregroundColor: .systemGray3)
        )
    )
    
    var feedbacks: PomeloFeedback?
    
    var text: PomeloTextStyle? = .init(textColor: .label,
                                       font: nil)
}

private extension UIColor {
    static var primaryColor: UIColor {
        return UIColor{ (traitCollection) -> UIColor in
            return traitCollection.userInterfaceStyle == .light ? UIColor(red: 0.30, green: 0.21, blue: 0.46, alpha: 1.00) : UIColor(red: 0.30, green: 0.21, blue: 0.46, alpha: 0.75)
        }
    }
    
    static var secondaryColor: UIColor {
        return UIColor{ (traitCollection) -> UIColor in
            return traitCollection.userInterfaceStyle == .light ? UIColor(red: 0.47, green: 0.35, blue: 0.65, alpha: 1.00) : UIColor(red: 0.47, green: 0.35, blue: 0.65, alpha: 0.75)
        }
    }
    
    static var backgroundColor: UIColor {
        .systemBackground
    }
    
    static var buttonBackgroundColor: UIColor {
        .primaryColor
    }
    
    static var butttonForegroundColor: UIColor {
        .white
    }
    
    static var disabledButtonBackgroundColor: UIColor {
        .systemGray6
    }
    
    static var disabledButtonForegroundColor: UIColor {
        .systemGray3
    }
}

With this theme your componets will looks like this card activation widget:

Dark mode: Every component of the SDK supports darkmode, you only have to set UIColors that support thios feature to build your custom PomeloTheme and every component will change it's color when the device configuration change.

For more information about how to use these component customization features you can go to Pomelo UI iOS docs.


Supported Languages

Now the SDK supports Spanish, Portuguese and English as preferred lanmguages. The user just have to select their preference language and the componebnts will show all the content in that language.

About

cards-ios-demo - Managed via CloudFormation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages