Sejam bem-vindos!
Neste README você encontra o passo a passo a ser feito para adicionar o Login com MeuID em seu app iOS (Swift e Objective C). Caso prefira, também temos os Samples dos dois apps aqui, basta baixar a pasta inteira. Para acessar o projeto em Swift, vá em sampleloginmeuid-ios > Swift > SampleLoginMeuID
e para acessar o projeto em ObjC, vá em sampleloginmeuid-ios > Obj-c > SampleLoginMeuID
. Segue nosso passo a passo em Swift e em Objective-C:
No projeto Sample, adicionamos o botão na Storyboard e configuramos seu layout na ViewController, definindo os 3 diferentes layouts que temos disponíveis. Criamos um enum para indicar o tipo do botão, porém se seu app vai usar apenas um estilo, não há a necessidade de colocar essa lógica em seu código. Segue o enum:
enum ButtonStyle {
case Purple
case WhiteWithoutBorder
case WhiteWithBorder
}
Em nossa documentação mostramos os layouts disponíveis.
Adicionamos as imagens do logo do MeuID na pasta Assets.xcassets
com os seguintes nomes:
- logo roxo: logo_meuid_purple
- logo branco: logo_meuid_white
Para aplicar apenas o layout roxo com texto em branco, adicione o seguinte código:
loginButton.tintColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
loginButton.setTitle("Login com MeuID", for: .normal)
loginButton.layer.cornerRadius = 8.0
loginButton.backgroundColor = #colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1)
let logo = UIImage(named: "logo_meuid_white")
loginButton.setImage(logo , for: .normal)
loginButton.imageEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 20)
Para aplicar apenas o layout branco com texto roxo e sem borda, adicione o seguinte código:
loginButton.tintColor = #colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1)
loginButton.setTitleColor(#colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1), for: .normal)
loginButton.setTitle("Login com MeuID", for: .normal)
loginButton.layer.cornerRadius = 8.0
loginButton.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
let logo = UIImage(named: "logo_meuid_purple")
loginButton.setImage(logo , for: .normal)
loginButton.imageEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 20)
Para aplicar apenas o layout branco com texto roxo e com borda roxa, adicione o seguinte código:
loginButton.tintColor = #colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1)
loginButton.setTitleColor(#colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1), for: .normal)
loginButton.setTitle("Login com MeuID", for: .normal)
loginButton.layer.cornerRadius = 8.0
loginButton.layer.borderColor = #colorLiteral(red: 0.4528235197, green: 0.3076393604, blue: 1, alpha: 1)
loginButton.layer.borderWidth = 1.0
loginButton.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
let logo = UIImage(named: "logo_meuid_purple")
loginButton.setImage(logo , for: .normal)
loginButton.imageEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 20)
Como nosso Sample envolve uma Storyboard, puxamos um IBAction
na ViewController e adicionamos ali a ação que deve ser feita ao clicar em nosso botão: abrir o deeplink que redirecionará para o app do MeuID.
@IBAction func didTapLogin(_ sender: UIButton) {
if let url = URL(string: getDeepLink()) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
Nessa função, chamamos uma outra função que criamos, com o nome de getDeeplink()
. Essa outra função, como diz o nome, serve para pegar o deeplink correto, e separamos ele para melhor entendimento de como o deeplink deve ser gerado.
Como dito em nossa documentação, cada aplicativo que quer usar o Login com MeuID deve ter um application id
para que o MeuID consiga identificar qual aplicativo está chamando. Sendo assim, no código abaixo você deve substituir o aplication_id
para o id que representa seu aplicativo.
let aplicationID = "application_id"
func getDeepLink() -> String {
return "meuid://meuid?action=MEUID_AUTHENTICATION&applicationId=\(aplicationID)¶meters=eyJvcmlnaW4iOiAiTU9CSUxFIn0="
}
Agora falta apenas o retorno recebido pelo app do MeuID!
Para que seu aplicativo receba a resposta de maneira correta do MeuID, deve ser adicionada uma configuração na raiz do projeto:
- Abrir
SeuProjeto > SeuTarget > Info > URL Types
- Clicar no botão
+
para adicionar uma URL Type - Em
URL Schemes
, adicionar:meuid-application_id
(lembrando que esteapplication_id
é o mesmo que foi adicionado na ViewController. Sendo assim, o padrão émeuid-
+ seu application id)
Na classe AppDelegate.swift
utilizamos a seguinte função:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let successStoryBoard = UIStoryboard(name: "Success", bundle: Bundle.main)
guard let viewController = successStoryBoard.instantiateViewController(withIdentifier: "SuccessViewController") as? SuccessViewController else { return true }
self.window?.rootViewController?.present(viewController, animated: true, completion: nil)
viewController.setParametersFromURL(url: url)
return true
}
Nela pegamos a url de retorno com os parâmetros que o MeuID envia (o code
e o code_verifier
). A obtenção dos parâmetros está na classe Success.swift
:
func setParametersFromURL(url: URL) {
if let codeParam = getQueryStringParameter(url: url.absoluteString, param: codeString),
let codeVerifierParam = getQueryStringParameter(url: url.absoluteString, param: codeVerifierString) {
codeLabel.text = "code: \(codeParam)"
codeVerifierLabel.text = "code_verifier: \(codeVerifierParam)"
}
}
// MARK: - Private Functions
private func getQueryStringParameter(url: String, param: String) -> String? {
guard let url = URLComponents(string: url) else { return nil }
return url.queryItems?.first(where: { $0.name == param })?.value
}
No projeto Sample, adicionamos o botão na Storyboard e configuramos seu layout na ViewController, definindo os 3 diferentes layouts que temos disponíveis. Criamos três funções diferentes para indicar o tipo do botão, porém se seu app vai usar apenas um estilo, não há a necessidade de colocar essa lógica em seu código.
Em nossa documentação mostramos os layouts disponíveis.
Adicionamos as imagens do logo do MeuID na pasta Assets.xcassets
com os seguintes nomes:
- logo roxo: logo_meuid_purple
- logo branco: logo_meuid_white
Para aplicar apenas o layout roxo com texto em branco, adicione o seguinte código:
- (void)setupLoginButtonPurple {
[self.loginButton setTitle: @"Login com MeuID" forState:UIControlStateNormal];
[self.loginButton setTintColor: UIColor.whiteColor];
[self.loginButton setBackgroundColor: [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00]];
self.loginButton.layer.cornerRadius = 8.0;
self.loginButton.clipsToBounds = YES;
UIImage *logo = [UIImage imageNamed:@"logo_meuid_white"];
[self.loginButton setImage:logo forState:UIControlStateNormal];
[self.loginButton setImageEdgeInsets:UIEdgeInsetsMake(8.0, 0.0, 8.0, 20.0)];
}
Para aplicar apenas o layout branco com texto roxo e sem borda, adicione o seguinte código:
- (void)setupLoginButtonWhiteWithoutBorder {
[self.loginButton setTitle: @"Login com MeuID" forState:UIControlStateNormal];
[self.loginButton setTintColor: [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00]];
[self.loginButton setTitleColor: [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00] forState:UIControlStateNormal];
[self.loginButton setBackgroundColor: UIColor.whiteColor];
self.loginButton.layer.cornerRadius = 8.0;
self.loginButton.clipsToBounds = YES;
UIImage *logo = [UIImage imageNamed:@"logo_meuid_purple"];
[self.loginButton setImage:logo forState:UIControlStateNormal];
[self.loginButton setImageEdgeInsets:UIEdgeInsetsMake(8.0, 0.0, 8.0, 20.0)];
}
Para aplicar apenas o layout branco com texto roxo e com borda roxa, adicione o seguinte código:
- (void)setupLoginButtonWhiteWithBorder {
[self.loginButton setTitle: @"Login com MeuID" forState:UIControlStateNormal];
[self.loginButton setTintColor: [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00]];
[self.loginButton setTitleColor: [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00] forState:UIControlStateNormal];
[self.loginButton setBackgroundColor: UIColor.whiteColor];
self.loginButton.layer.cornerRadius = 8.0;
self.loginButton.layer.borderColor = [UIColor colorWithRed: 0.43 green: 0.31 blue: 0.96 alpha: 1.00].CGColor;
self.loginButton.layer.borderWidth = 1.0;
self.loginButton.clipsToBounds = YES;
UIImage *logo = [UIImage imageNamed:@"logo_meuid_purple"];
[self.loginButton setImage:logo forState:UIControlStateNormal];
[self.loginButton setImageEdgeInsets:UIEdgeInsetsMake(8.0, 0.0, 8.0, 20.0)];
}
Como nosso Sample envolve uma Storyboard, puxamos um IBAction
na ViewController e adicionamos ali a ação que deve ser feita ao clicar em nosso botão: abrir o deeplink que redirecionará para o app do MeuID. O IBAction no arquivo .m da ViewController fica assim:
- (IBAction)didTapLogin:(UIButton *)sender {
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString: [self getDeeplink]];
[application openURL:URL options:@{} completionHandler:nil];
}
Nessa função, chamamos uma outra função que criamos, com o nome de [getDeeplink]
. Essa outra função, como diz o nome, serve para pegar o deeplink correto, e separamos ele para melhor entendimento de como o deeplink deve ser gerado.
Como dito em nossa documentação, cada aplicativo que quer usar o Login com MeuID deve ter um application id
para que o MeuID consiga identificar qual aplicativo está chamando. Sendo assim, no código abaixo você deve substituir o aplication_id
para o id que representa seu aplicativo. No arquivo .h da ViewController, adicionamos a propriedade do aplication_id
:
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
E no .m da ViewController, temos a função que define o deeplink correto:
- (NSString *)getDeeplink {
_applicationID = @"applicationID";
return [NSString stringWithFormat:@"meuid://meuid?action=MEUID_AUTHENTICATION&applicationId=%@¶meters=eyJvcmlnaW4iOiAiTU9CSUxFIn0=", _applicationID];
}
Agora falta apenas o retorno recebido pelo app do MeuID!
Para que seu aplicativo receba a resposta de maneira correta do MeuID, deve ser adicionada uma configuração na raiz do projeto:
- Abrir
SeuProjeto > SeuTarget > Info > URL Types
- Clicar no botão
+
para adicionar uma URL Type - Em
URL Schemes
, adicionar:meuid-application_id
(lembrando que esteapplication_id
é o mesmo que foi adicionado na ViewController. Sendo assim, o padrão émeuid-
+ seu application id)
Na classe AppDelegate.m
utilizamos a seguinte função:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
NSString * storyboardName = @"Success";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
SuccessViewController *successViewController = [storyboard instantiateViewControllerWithIdentifier:@"SuccessViewController"];
[self.window.rootViewController presentViewController:successViewController animated:YES completion:nil];
[successViewController setParametersFromURL:url];
return YES;
}
Nela pegamos a url de retorno com os parâmetros que o MeuID envia (o code
e o code_verifier
). A obtenção dos parâmetros está na classe SuccessViewController.m
:
- (void)setParametersFromURL:(NSURL *)url {
NSString *code = [self queryParametersFromURL:url][@"code"];
NSString *codeVerifier = [self queryParametersFromURL:url][@"code_verifier"];
self.codeLabel.text = [_codeLabel.text stringByAppendingString:code];
self.codeVerifierLabel.text = [_codeVerifierLabel.text stringByAppendingString:codeVerifier];
}
- (NSDictionary<NSString *, NSString *> *)queryParametersFromURL:(NSURL *)url {
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableDictionary<NSString *, NSString *> *queryParams = [NSMutableDictionary<NSString *, NSString *> new];
for (NSURLQueryItem *queryItem in [urlComponents queryItems]) {
if (queryItem.value == nil) { continue; }
[queryParams setObject:queryItem.value forKey:queryItem.name];
}
return queryParams;
}