CocoaPods trunk is moving to be read-only. Read more on the blog, there are 18 months to go.

FlipConnectSDK 0.4.1

FlipConnectSDK 0.4.1

TestsTested
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Aug 2017
SwiftSwift Version 3.0
SPMSupports SPM

Maintained by Munir Wanis.



  • By
  • Munir Wanis

FlipConnectSDK

Build Status codebeat badge

Veja mais aqui: FlipConnectSDK Reference

Como funciona

A FlipConnectSDK funciona recebendo ClientId e ClientSecret para abrir uma página web para logar exatamente como na autenticação do Facebook e do Google. O usuário irá logar no nosso ambiente e, caso seja bem sucedido, o usuário será redirecionado para a aplicação usando a previamente configurada RedirectURI.

Quando a aplicação abre, a SDK irá procurar por parâmetros válidos na URI, para que então possa fazer requisições para recuperar o accesToken, o refreshToken e a userKey.

Com essas informações você será capaz de acessar as informações do usuário!

Instalação

Instalação manual

Para instalar manualmente a SDK é necessário baixar o .zip FlipConnectSDK_Manual.framework.zip e colocar em Embedded Binaries como na imagem abaixo:

Manual Installation

Depois é necessário baixar o script remove_unused_archs.sh e adicionar em Build Phases > Run Script o seguinte comando: bash "${SRCROOT}/remove_unused_archs.sh" (lembrando que neste caso o script está no root do projeto, se o seu script estiver em outra pasta é necessário informar o caminho desta pasta) como na imagem abaixo:

Run Script

Estes passos são necessários para rodar o script manual porque ambos os frameworks contém todos as arquiteturas dentro dele, mas a loja da Apple não permite publicar o app com as arquiteturas de simulador, por isso este post script garante a remoção destas arquiteturas para que a publicação ocorra sem problemas.

Usabilidade

Configuração

No seu projeto, clique na aba “informação” e selecione Url Types. No campo identifier, é obrigatório que o nome seja FlipConnectSDK, e na URL Schemes você deve colocar o esquema que foi configurado para seu Merchant URI, por exemplo:

Se a Merchant URI registrada é flipConnect://application sua Url Schemes deve ser flipConnect; em outras palavras, tudo antes de :// é sua Url Scheme.

Url Schema Creation

Inicialização

É necessário inicializar a classe de login na abertura do app no AppDelegate.swift, e colar o código abaixo. O parâmetro fingerPrintID é opcional, deve ser passado apenas se quiser utilizar o anti-fraude.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        let config = FCConfiguration(
            environment: .sandbox,
            clientID: "{SEU_CLIENT_ID}",
            clientSecret: "{SEU_CLIENT_SECRET}",
            redirectURI: "{SUA_REDIRECT_URI}", // EX: flipconnect://application
            fingerPrintID: "{SEU_FINGERPRINT_ID}"
        )
        do {
            _ = try FCLogin.shared()
        } catch {
            print(error)
        }
        return true
    }

Após esta inicialização, se for passado o fingerPrintID, o fingerPrintSessionID será setado e você poderá acessá-lo chamando o UserDefaults como no exemplo abaixo:

if let fingerPrintSessionID = UserDefaults.standard.fingerPrintSessionID {
    print(fingerPrintSessionID)
}

ViewController

O login terá início aqui. Alguma ação irá ativar a página de login; se tudo funcionar corretamente, a página web irá redirecionar de volta para a aplicação.

Você pode usar seu próprio botão ou usar o nosso.

No seu ViewController importe a SDK:

import FlipConnectSDK

Logar com o botão

class ViewController: UIViewController {

    var fcLogin: FCLogin!

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            fcLogin = try FCLogin.shared()

            let loginBtn = fcLogin.loginWithButton(center: view.center, frame: CGRect(x: 0, y: 0, width: 180, height: 40), color: .darkGray, title: "FlipConnect Login")
            view.addSubview(loginBtn)

        } catch {
            print(error)
        }
    }
}

O botão parecerá com algum destes:

Login Button

Logar com openLoginURL

class ViewController: UIViewController {

    var fcLogin: FCLogin!

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            fcLogin = try FCLogin.shared()
        } catch {
            print(error)
        }
    }

    @IBAction func loginAction(_ sender: UIButton) {
        self.fcLogin.loginButtonClicked()
    }
}

Enviando dados de FingerPrint para o anti-fraude (opcional)

Com o FingerPrintID sendo enviado na inicialização da classe FCLogin, enviar dados para o anti-fraude é muito simples, basta colocar permissões no seu app para o usuário liberar acesso aos contatos e o mesmo para localização.

OBS: Lembre-se que a Apple pode encrencar com a publicação do seu app se ele pedir permissão ao usuário de dados que são desnecessários para o app, não vale pedir acesso aos contatos do seu usuário se o seu app não faz nada com os contatos dele, não é mesmo?

Para pedir as permissões de acesso para o usuário basta acrescentar estas linhas no Info.plist:

Privacy Access

Transferência de Dados para Perfil temporário

Se desejar transferir os dados de cadastro que já tem em sua base para facilitar o cadastro e a transição do usuário para o nosso sistema, você pode usar a variável temporaryProfile para preencher os dados cadastrais do usuário.

Para utilizar basta atribuir um valor do tipo TemporaryProfile a variável temporaryProfile da classe FCLogin:

class ViewController: UIViewController {

    var fcLogin: FCLogin!

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            fcLogin = try FCLogin.shared()

        let formatter = DateFormatter()
            formatter.dateFormat = "yyyy/MM/dd"
            let birthdate = formatter.date(from: "1997/12/17")
            
            let personalData = PersonalData(birthdate: birthdate, genderType: .masculine, country: "br", dependentCount: 3)!
            let vehicle = Vehicle(licensePlate: "LNY-4266", licensePlateCity: "Rio de Janeiro", licensePlateState: "RJ", licensePlateCountry: "br")!
            let vehicle2 = Vehicle(licensePlate: "LNY-4266", licensePlateCity: "Rio de Janeiro", licensePlateState: "RJ", licensePlateCountry: "br")!
            let document = Document(documentType: .cpf, documentNumber: "12345678901")!
            let phone = Phone(phoneType: .mobile, fullNumber: "26113328")!
            let phone2 = Phone(phoneType: .home, fullNumber: "26113328")!
            let address = Address(street: "Conde de Bonfim", number: "800", addressType: .work, city: "Rio de Janeiro", state: "RJ", country: "br")!
            let address2 = Address(street: "Conde de Bonfim", number: "800", addressType: .work, city: "Rio de Janeiro", state: "RJ", country: "br")!
            
            let temporaryProfile = TemporaryProfile()
            temporaryProfile.addresses = [address, address2]
            temporaryProfile.documents = [document]
            temporaryProfile.personalData = personalData
            temporaryProfile.phones = [phone, phone2]
            temporaryProfile.vehicles = [vehicle, vehicle2]

        fcLogin.temporaryProfile = temporaryProfile
        } catch {
            print(error)
        }
    }

    @IBAction func loginAction(_ sender: UIButton) {
        self.fcLogin.loginButtonClicked()
    }
}

Ou na chamada do método loginWithButton():

class ViewController: UIViewController {

    var fcLogin: FCLogin!

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            fcLogin = try FCLogin.shared()

        let formatter = DateFormatter()
            formatter.dateFormat = "yyyy/MM/dd"
            let birthdate = formatter.date(from: "1997/12/17")
            
            let personalData = PersonalData(birthdate: birthdate, genderType: .masculine, country: "br", dependentCount: 3)!
            let vehicle = Vehicle(licensePlate: "LNY-4266", licensePlateCity: "Rio de Janeiro", licensePlateState: "RJ", licensePlateCountry: "br")!
            let vehicle2 = Vehicle(licensePlate: "LNY-4266", licensePlateCity: "Rio de Janeiro", licensePlateState: "RJ", licensePlateCountry: "br")!
            let document = Document(documentType: .cpf, documentNumber: "12345678901")!
            let phone = Phone(phoneType: .mobile, fullNumber: "26113328")!
            let phone2 = Phone(phoneType: .home, fullNumber: "26113328")!
            let address = Address(street: "Conde de Bonfim", number: "800", addressType: .work, city: "Rio de Janeiro", state: "RJ", country: "br")!
            let address2 = Address(street: "Conde de Bonfim", number: "800", addressType: .work, city: "Rio de Janeiro", state: "RJ", country: "br")!
            
            let temporaryProfile = TemporaryProfile()
            temporaryProfile.addresses = [address, address2]
            temporaryProfile.documents = [document]
            temporaryProfile.personalData = personalData
            temporaryProfile.phones = [phone, phone2]
            temporaryProfile.vehicles = [vehicle, vehicle2]

        let btn = fcLogin.loginWithButton(center: view.center, temporaryProfile: temporaryProfile)

        view.addSubview(btn)
        } catch {
            print(error)
        }
    }

    @IBAction func loginAction(_ sender: UIButton) {
        self.fcLogin.loginButtonClicked()
    }
}

Com isso a tela de cadastro irá se abrir com os dados já preenchidos no ato do cadastro do usuário.

AppDelegate

Após um login bem sucedido, o redirecionamento passará por aqui com alguma informação de login, porém apenas depois do método handleRedirect(fromURL: URL) funcionar sem problemas é que nós seremos capazes de recuperar o Token Data.

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        do {
            let fcLogin = try FCLogin.shared()
            fcLogin.handleRedirect(fromURL: url) { tokenResponse, error in

                guard error == nil else {
                    print(error!)
                    return
                }

                if tokenResponse.success {
                    // DO SOMETHING
                    print(tokenResponse.accessToken!)
                    print(tokenResponse.userKey!)
                    print(tokenResponse.refreshToken!)
                }
            }
        } catch {
            print(error)
        }
        
        return true
    }
}

Você deverá ser capaz de usar o accessToken, refreshToken e a userKey se digitar o seguinte:

let accessToken: String? = UserDefaults.standard.accessToken
let userKey: String? = UserDefaults.standard.userKey
let refreshToken: String? = UserDefaults.standard.refreshToken

Refresh Token

Se o token expirar, basta fazer a implementação que segue. Se algum erro retornar ou o sucesso do tokenResponse for false, é porque a requisição foi mal-sucedida

do {
    let fcLogin = try FCLogin.shared()

    FCApi.requestTokenRefresh() { tokenResponse, error in
        guard error == nil else {
            print("Refresh with NO success")
            print(err!)
            return
        }

            if tokenResponse.success {
                // DO SOMETHING
                print("Tokens Refreshed")
                print(tokenResponse.accessToken!)
                print(tokenResponse.userKey!)
                print(tokenResponse.refreshToken!)
            } else {
                // ERROR HANDLING
                var message = ""
                for report in tokenResponse.operationReport {
                    message.append("\(report.field) - \(report.message)")
                }
            }
    }

} catch {
    print(error)
}

Verificar o Token

Se algum erro retornar ou o sucesso do tokenResponse for false, é porque a requisição foi mal-sucedida e/ou o token verificado é inválido

do {
    let fcLogin = try FCLogin.shared()

    FCApi.requestTokenVerification() { tokenResponse, error in
            guard error == nil else {
                print("Verify with NO success")
        print(err!)
                return
            }
            
            if tokenResponse.success {
                // DO SOMETHING
                print(tokenResponse.accessToken!)
                print(tokenResponse.userKey!)
            } else {
                // ERROR HANDLING
                var message = ""
                for report in tokenResponse.operationReport {
                    message.append("\(report.field) - \(report.message)")
                }
                print(message)
            }
    }

} catch {
    print(error)
}

Revogar Token

Para revogar o Token do usuário, basta chamar o método requestTokenRevocation como no exemplo abaixo:

do {
    let fcLogin = try FCLogin.shared()

        FCApi.requestTokenRevocation() { tokenResponse, error in
            guard error == nil else {
                self.showErrorDialog("\(error!)")
                return
            }
            
            if tokenResponse.success {
                // DO SOMETHING
                print("Logged out")
            } else {
                // ERROR HANDLING
                var message = ""
                for report in tokenResponse.operationReport {
                    message.append("\(report.field) - \(report.message)")
                }
                print(message)
            }

} catch {
    print(error)
}

Contribuições

Pull Requests serão muito bem-vindos!

Problemas

Algum problema, dúvida ou sugestão? Abra uma issue!