Skip to content

Documentação

rbrauwers edited this page Oct 24, 2023 · 17 revisions

Configurações Merci-Kit iOS

Informações:

Merci-Kit utiliza o IDFA (Identifier for Advertisers).

Quando for realizar uma entrega na App Store é necessário dizer que está sendo utilizado.

✅ - Yes {Does this app use the Advertising Identifier (IDFA)?}

✅ - Attribute this app installation to a previously served advertisement

✅ - Attribute an action taken within this app to a previously served advertisement

✅ - Limit ad tracking setting in iOS

Pré-Requisitos

    - iOS version: 10.0 ou superior
    - Swift: 5.4.0
    - CocoaPods
    - Info.plist

Credenciais:

A Dock fornece as credenciais Client-Id e Client-Secret, que são necessárias para instanciar a SDK. Para gerar as credenciais, é necessário que envie para o time de setup o appId (package name/id).

Dependências:

CocoaPods

    - Alamofire - <= 4.9.1
    - Kingfisher
    - KeychainAccess <= 4.2.0
    - TPKeyboardAvoiding - 1.3
    - SwiftyRSA - >= 1.5.0

Info.plist:

<key>NSCameraUsageDescription</key>
<string>DESCRIÇÃO</string>
<key>NSFaceIDUsageDescription</key>
<string>DESCRIÇÃO</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>DESCRIÇÃO</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>DESCRIÇÃO</string>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>waze</string>
    <string>comgooglemaps</string>
    <string>uber</string>
    <string>cydia</string>
</array>

Configuração

Para configurar o MCIKit em seu projeto adicione as dependências no Podfile:

target 'YourTarget' do
    use_frameworks!
    pod 'MCIKit', :git =>'https://github.com/merci-app/mcikit-podspec', :tag => "1.9.8"
    pod 'MarketPlaceKit', :git =>'https://github.com/merci-app/marketplacekit-podspec', :tag => "1.9.8"
    pod 'PayKit', :git =>'https://github.com/merci-app/paykit-podspec', :tag => "1.9.8"
    pod 'WithdrawalKit', :git =>'https://github.com/merci-app/withdrawalkit-podspec', :tag => "1.9.8"
end

 ########
 # Workaround until Cocoapdos fix 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0
 # Workaround ultil Cocoapods fix 'BUILD_LIBRARY_FOR_DISTRIBUTION' isn't set
 ########
 post_install do |installer|
   installer.pods_project.targets.each do |target|
     target.build_configurations.each do |config|
       config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
       config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
     end
   end
 end

Whitelist

Para a utilização do SDK é necessário o envio de algumas informações do aplicativo cliente para que o mesmo entre na nossa lista de Whitelist. Para isso é necessário enviar as seguintes informações:

AppId: O mesmo usado para a App Store do. Ex.: com.ios.app.cliente

API

Deverá ser fornecido uma API REST que possua uma rota autenticada para que seja possível realizar a validação do token fornecido pelo aplicativo. Nessa API iremos enviar o token e o vat-number, a API deverá responder com um código de retorno 2XX quando válido e 4XX para informações invalidas.

Exemplo

REST URL: https://BASE_URL/VALIDATION_PATH
METHODS: [POST|PUT|DELETE]
REQUEST: {
    vatNumber: "",
    token: ""
}
RESPONSE:
RESPONSE CODE: [2XX|4XX]

Inicialização

A framework deverá ser iniciada dentro do application delegate como a seguir:

import UIKit
import MerciKit
import MarketPlaceKit
import PayKit
import WithdrawalKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    lazy var merciDelegate = SampleDelegate()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
       
        Merci.instantiate(
            clientId: <#String#>, // Veja o tópico Credenciais acima
            clientSecret: <#String#>, // Veja o tópico Credenciais acima
            environment: <#MerciEnvironment>,
            clientName: <#String?#>,
            homeImage: <#UIImage?#>,
            merciBrandImage: <#UIImage?#>,
            homeBackgroundColor: <#UIColor?#>,
            homeTitleColor: <#UIColor?#>,
            actionBarTintColor: <#UIColor?#>,
            actionTintColor: <#UIColor?#>,
            actionTextTintColor: <#UIColor?#>,
            loadingTintColor: <#UIColor?#>,
            clientSecurityDelegate: <#MerciClientSecurityDelegate?#>,
            delegate: <#MerciDelegate?#>
        )

        MarketPlace.register()
        Pay.register()
        Withdrawal.register()
        
        return true
    }

}

A instrução de delegação é opcional e utiliza o seguinte protocol

public protocol MerciClientSecurityDelegate {
    func externalToken() -> String
}

Nota: Migração para novo padrão a partir da versão 1.9.3 use link para mais detalhes.

Caso seja necessário implementar, segue abaixo um exemplo:

import MerciKit

class SampleSecurityDelegate: MerciClientSecurityDelegate {

    public func externalToken() -> String {
        return "0123456789"
    }

}


A instrução de delegação é opcional e utiliza o seguinte `protocol`:
````swift
public protocol MerciDelegate {
    func supportFlow(reason: String?) -> UIViewController?
    func authenticationFlow() -> UIViewController
    func withdrawSupport() -> UIViewController?
}

Caso seja necessário implementar, segue abaixo um exemplo:

import UIKit
import MerciKit

class SampleDelegate: MerciDelegate {

    func supportFlow(reason: String?) -> UIViewController? {
        debugPrint(reason ?? "")
        return nil
    }
    
    func authenticationFlow() -> UIViewController {
        return UIViewController()
    }
    
}

Autenticação

Para utilizar os recursos da framework é necessário autenticar o usuário como exibido a seguir:

import MerciKit

Merci.authenticate(cpf: <#String#>) { [weak self] (result) in
    guard let self = self else { return }
  
    switch result {
    case .success:
        debugPrint("OK")
    
    case .failure(let error):
        debugPrint(error)
    }
}

Para realizar o logout:

Merci.revokeAuthentication { [weak self] (result) in
    switch result {
    case .success:
        debugPrint("OK")

    case .failure(error)
        debugPrint(error)
    }
}

Para checar se o usuário esta autenticado na nossa plataforma:

Merci.isAuthenticated()

O proceso de autenticação deve ocorrer uma única vez. Sugerimos efetuar a autenticação da SDK Merci logo após efetuarem o processo de login do seu aplicativo.

Sempre que o usuário efetuar logout em seu aplicativo, é obrigatório chamar o método Revoke em nossa SDK.

Iniciar uma venda

Para iniciar uma venda direta, é necessário chamar o método abaixo, informando o identifcador do estabelecimento como mostra a seguir:

import UIKit
import MerciKit

Merci.launch(viewController: <#UIViewController#>, module: .merchant(<#merchant id: String#>)) { result in 
    switch result {
    case .success:
    debugPrint("Merchant available.")
    
    case .failure(let error):
    debugPrint("Merchant not found.")
    }
}

Iniciar a marketpay

Para iniciar a marketpay, é necessário chamar o método abaixo:

Merci.launch(viewController: self, module: .marketpay) { (result) in
    switch result {
        case .success:
            debugPrint("OK.")

        case .failure(let error):
            debugPrint(error)
    }
}

Inciar o pagar

Para iniciar o pagar, é necessário chamar o método abaixo:

Merci.launch(viewController: self, module: .pay) { (result) in
    switch result {
        case .success:
            debugPrint("OK.")

        case .failure(let error):
            debugPrint(error)
    }
}

Inciar o sacar

Para iniciar o sacar, é necessário chamar o método abaixo, caso enableSupport for true, será exibido um ícone de help (?) e quando o usuário clicar será executado o delegate withdrawSupport:

Merci.launch(viewController: self, module: .withdrawal(enableSupport: false)) { (result) in
    switch result {
        case .success:
            debugPrint("OK.")

        case .failure(let error):
            debugPrint(error)
    }
}

Notificações

Nota: Os objetos expostos nas notificações são todos no padrão JSON, permitindo a fácil leitura por qualquer plataforma.

Notificação de autenticação:

Esta notificação retorna o horário em formato de timestamp numérico e o status como autenticado authentticated ou revogado revoked.

Nome da notificação:

Merci.userAuthenticationNotification

Valor:

"MerciSDK_UserAuthenticationNotification"

Objeto retornado na notificação:

{
    "timestamp": "1573728019",
    "status": "authenticaded|revoked"
}

Notificação de modulo:

Esta notificação retorna o horário em formato de timestamp numérico, o module como marketplace, payment, wallet e o status como apresentado presented ou dispensado dismissed.

Nome da notificação:

Merci.modulePresentationNotification

Valor:

"MerciSDK_ModulePresentationNotification"

Objeto retornado na notificação:

{
    "timestamp": "1573728019",
    "module": "marketplace|payment|wallet",
    "status": "presented|dismissed"
}

Notificação de apresentação de estabelecimento:

Esta notificação retorna o horário em formato de timestamp numérico, o merchant com informações do identificador id, nome name, logo em seguida o status como apresentado presented ou dispensado dismissed.

Nome da notificação:

Merci.merchantPresentationNotification

Valor:

"MerciSDK_MerchantPresentationNotification"

Objeto retornado na notificação:

{
    "timestamp": "1573728019",
    "merchant": {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "Nome do estabelecimento"
    },
    "status": "presented|dismissed"
}

Notificação de transação:

Esta notificação retorna o horário em formato de timestamp numérico, o merchant com informações do identificador id, nome name, logo em seguida o valor amount decimal, status como iniciado started, cancelado canceled, erro failed, concluído completed.

Nome da notificação:

Merci.transactionNotification

Valor:

"MerciSDK_TransactionNotification"

Objeto retornado na notificação:

{
    "timestamp": "1573728019",
    "merchant": {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "Nome do estabelecimento"
    },
    "amount": 123.45,
    "status": "started|canceled|failed|completed"
}

Exemplo

    let nc = NotificationCenter.default
    nc.addObserver(forName: Merci.userAuthenticationNotification, object: nil, queue: .main) { (notification) in
        guard let dict = notification.object as? [String: Any] else {
            return
        }
        // dict["timestamp"]
        // dict["status"]
        <#code#>
    }

Troubleshooting

Address sanitizer

Exemplo de runtime error ao acessar alguma feature da SDK:

Address 0x00016a808200 is a wild pointer inside of access range of size 0x000000000001.
SUMMARY: AddressSanitizer: bad-free (/private/var/containers/Bundle/Application/B5A53E42-139B-4CD6-9666-2583934022C3/SDKTester+Pods.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib:arm64e+0x53438) in wrap_free+0x98
==1377==ABORTING
warning: Module "/Users/rodrigobrauwers/Library/Developer/Xcode/DerivedData/Sample-cabgnrfbofthefbyvbylruutvhct/Build/Products/Debug-iphoneos/SDKTester+Pods.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib" uses triple "arm64e-apple-ios14.0.0", which is not compatible with the target triple "arm64-apple-ios10.0.0". Enabling per-module Swift scratch context.
AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.

Solução: desabilitar o address sanitizer nas configurações do scheme, conforme ilustrado abaixo. Address sanitizer

Merci @ 2021