SlideShare uma empresa Scribd logo
1 de 64
11
XAMARIN.FORMS + AZURE: UM ESTUDO
DE CASO
Oberdan Ferreira
22
XAMARIN.FORMS + AZURE: UM ESTUDO
DE CASO
Oberdan Ferreira
SOBRE MIM | Oberdan Ferreira
Principal Engineer @ArcTouch
@oberdanferreira
oberdan.bitencourt@gmail.com
• INTRODUÇÃO
• AUTENTICAÇÃO COM AZURE ACTIVE DIRECTORY
• INTEGRAÇÃO COM AZURE STORAGE
• BLOB
• QUEUE
• AZURE NOTIFICATIONS HUB (PUSH NOTIFICATIONS)
• COMUNICAÇÃO EM TEMPO REAL COM SIGNALR
AGENDA
• Grey Global Group
• Uma agência global de marketing e propaganda
• Utiliza serviços Microsoft (AD, API Apps, DocumentDb,
etc.)
• Bancos de dados mantém dados legados
• A Grey emprega mais de 1500 funcionários.
INTRODUÇÃO | ESTUDO DE CASO - GREY
• Como surgiu a ideia do app?
• Necessidade de conectar seus funcionários com colegas de
trabalho
• Atualizar funcionários com notícias sobre a empresa
• Alertá-los sobre eventos que estão para ocorrer
INTRODUÇÃO | ESTUDO DE CASO - GREY
• Backend Microsoft
• Active Directory
• API Apps no Azure
INTRODUÇÃO | ESTUDO DE CASO - GREY
=
AUTENTICAÇÃO COM AD
• Possibilita login no app por qualquer funcionário da empresa com
baixo esforço.
• Autenticação gerenciada pela Microsoft
• Autenticação Cross Platform (Android, iOS)
• Refresh de OAuth token é automático
• Compartilhar token p/ chamadas a API
AUTENTICAÇÃO | ADAL - PRÓS
• Autenticação gerenciada pela Microsoft - pouca customização.
• Cliente não entende que não dá pra trocar o layout da webview.
• Trocar Profile da PCL para usar as versões mais atuais
• v. 3.13.19 - PCL7 (sem Windows 8.1 ou 10)
• Exige configuração no lado do servidor para autorizar o token via Azure
Portal.
• Na época o AD era gerenciado via manage.windowsazure.com
• APIs hospedadas em portal.azure.com
AUTENTICAÇÃO | ADAL - CONTRAS
AUTENTICAÇÃO | ADAL - Criar App no AD
AUTENTICAÇÃO | ADAL
AZURE STORAGE | Integração com Xamarin
private async Task<AuthenticationResult> Authenticate(string authority, string resource, string
clientId, string returnUri)
{
var authContext = new AuthenticationContext(authority);
var authResult = await authContext
.AcquireTokenAsync(
resource, //https://login.microsoftonline.com/common
clientId, //valor registrado no Azure
uri, //valor registrado no Azure
PlatformAuthenticator.PlatformParameters);
//Pego via DependencyService.
//Android: new PlatformParameters((Activity)Forms.Context)
//iOS: new PlatformParameters(UIApplication
.SharedApplication
.KeyWindow
.RootViewController);
return authResult;
// contém informações básicas do usuário logado e OAuth token
}
AZURE STORAGE | Integração com Xamarin
AZURE STORAGE
AZURE STORAGE | Overview
• Permite hospedagem de arquivos (imagens, documentos, etc),
mensagens, tabelas
• Arquivos somente podem ser acessados por meio de um Shared Access
Token
• Mensagens podem ser enfileiradas com confiabilidade
• Redundância de dados nos servidores espalhados pelo mundo
• Consistência dos dados (garantir que sempre a última versão será
utilizada)
AZURE STORAGE | BLOB - Utilização no App
• Utilizado para salvar fotos de perfil dos funcionários
• Imagens enviadas para um Blob Storage
• Blob é lido por um job controlado pelo cliente
• Imagem é atualizada no banco de dados do cliente (inacessível por
nós)
• API de pessoas retornava a foto de perfil apontando para o Azure
AZURE STORAGE | QUEUE - Utilização no App
• Queue utilizada para atualizar preferências do app para cada funcionário
• Mensagem enviada em formato JSON
• Queue é lida por um Azure Job controlado pelo cliente
• Job atualiza o backend do cliente
• Problema: demora cerca de 4 minutos para a informação ser processada
(provavelmente por configuração/performance do lado do cliente)
DEMO
CRIANDO STORAGE ACCOUNT
AZURE STORAGE | Integração com Xamarin
• Últimas versões rodam no .NET Standard (e instalam uma porrada de
dependências)
• Falha ao instalar
System.Runtime.InteropServices.RuntimeInformation.4.0.0
• Dica: Instale o
System.Runtime.InteropServices.RuntimeInformation4.3.0 antes!
AZURE STORAGE | Integração com Xamarin
PCL COM XAMARIN.FORMS .RUNTIMEINFORMATION
PCL COM XAMARIN.FORMS
+ WINDOWSAZURE.STORAGE
V8.1.1
SHOW ME THE CODE
BLOB
const string STORAGE_IMAGE_BLOB = "tdc-blob";
const string STORAGE_CONNECTION_STRING =
“DefaultEndpointsProtocol=https;AccountName=tdc;AccountKey……”;
private CloudBlobContainer GetContainer()
{
// configura a conta
var account = CloudStorageAccount.Parse(STORAGE_CONNECTION_STRING);
// cria um blob client
var client = account.CreateCloudBlobClient();
// pega o contêiner criado no Azure
var container = client.GetContainerReference(STORAGE_IMAGE_BLOB);
return container;
}
public async Task<string> UploadImageAsync(Stream image)
{
var container = GetContainer();
// tenta criar contêiner se ele não existir
await container.CreateIfNotExistsAsync();
var name = $"{Guid.NewGuid().ToString("D")}.jpg";
// cria uma referência de Blob para salvar o arquivo
var imageBlob = container.GetBlockBlobReference(name);
// faz o upload assíncrono do stream
await imageBlob.UploadFromStreamAsync(image);
// retorna o novo nome do arquivo para
// fazer o download no futuro
return name;
}
public async Task<byte[]> GetImageAsync(string name)
{
// pega o contêiner
var container = GetContainer();
// pega referência pra imagem pelo nomo do arquivo
var blob = container.GetBlobReference(name);
if (await blob.ExistsAsync())
{
// se existir, pega os atributos
await blob.FetchAttributesAsync();
byte[] blobBytes = new byte[blob.Properties.Length];
// faz download do byte array
await blob.DownloadToByteArrayAsync(blobBytes, 0);
return blobBytes;
}
return null;
}
SHOW ME THE CODE
QUEUE
public async Task AddMessageAsync(string message)
{
try
{
var cloudQueue = GetCloudQueue();
// cria fila caso não exista
await cloudQueue.CreateIfNotExistsAsync();
// envia mensagem pra fila
await cloudQueue.AddMessageAsync(
new CloudQueueMessage(message));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
public async Task<string> GetLastMessageAsync()
{
try
{
var cloudQueue = GetCloudQueue();
await cloudQueue.CreateIfNotExistsAsync();
// lê mensagem da fila
CloudQueueMessage queue = await
cloudQueue.GetMessageAsync();
// remove mensagem lida
await cloudQueue.DeleteMessageAsync(queue);
// retorna como string
return queue.AsString;
}
catch (Exception ex) { … }
NOTIFICATION HUBS
• Push Notifications utilizados para alertar usuários sobre
novas notícias, alertar sobre eventos
• Backend integra com Azure e disparava os push notifications
NOTIFICATION HUBS | Utilização no app
• Possibilita enviar Push Notifications para várias plataformas
(iOS, Android, Windows, Kindle e Baidu)
• SDK em .NET, Node.JS, Java e PHP
• Push Notifications direcionados com tags
• Grátis até 1 milhão de Push Notifications enviados
AZURE | Notification Hubs
• Gerar um Certificate Signing Request File na sua máquina
• Ir até developer.apple.com
• Criar certificado de Push Notification com base no CSR criado na sua máquina
• Baixar o .cer e instalar na sua máquina
• Abrir o Keychain Access no macOS e exportar o certificado em formato .p12
• Criar um Provisioning Profile em developer.apple.com usando o .p12
• Incluir os devices registrados no Provisioning Profile (você não pode distribuir o app para
qualquer device)
• Gerar, baixar e instalar o Provisioning Profile
NOTIFICATION HUBS | IOS
NOTIFICATION HUBS | Android
NOTIFICATION HUBS | Criando NotificationHub
NOTIFICATION HUBS | Integração com Xamarin
NOTIFICATION HUBS | Integração com Xamarin
IOS
public override bool FinishedLaunching(UIApplication app, NSDictionary
options)
{
// Gerencia notificações recebidas com app fechado ao
// abrir
ProcessNotification(options);
// Registra para receber notificações
// Popup vai aparecer para o usuário
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(
UIRemoteNotificationType.Alert |
UIRemoteNotificationType.Badge |
UIRemoteNotificationType.Sound);
...
}
public override void RegisteredForRemoteNotifications(UIApplication app, NSData deviceToken)
{
// Cria conexão com Azure Notification Hub
// Pegar parâmetros no Azure Portal
var cs = SBConnectionString.CreateListenAccess(
new NSUrl("sb://seuservicebus-ns.servicebus.windows.net/"),
"SUA-KEY");
// Registrar device no azure
var hub = new SBNotificationHub(cs, "seu-hub-name");
hub.RegisterNativeAsync(deviceToken, null, err =>
{
if (err != null)
Console.WriteLine("Erro: " + err.Description);
else
Console.WriteLine($”Sucesson Token: {deviceToken}“);
});
}
public override void ReceivedRemoteNotification(UIApplication app, NSDictionary
userInfo)
{
// Processa a notificação recebida com o app aberto
// Iterar sobre o userInfo e processar a informação recebida
// ex.: navegar para uma página
ProcessNotification(userInfo);
}
ANDROID
No AssemblyInfo.cs do projeto Droid adicionar:
// Permissão que notifica o app que o device terminou de ligar
[assembly: UsesPermission(Android.Manifest.Permission.ReceiveBootCompleted)]
Criar um BroadcastReceiver:
[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
namespace XamarinFormsAzure.Droid
{
[BroadcastReceiver(Permission = Gcm.Constants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new[] { Intent.ActionBootCompleted } )] // Permite gerenciar push com app fechado
[IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_MESSAGE }, Categories = new[] { "@PACKAGE_NAME@" } )]
[IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new[] {
"@PACKAGE_NAME@" } )]
[IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new[] { "@PACKAGE_NAME@" } )]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" }, Categories = new[] { "@PACKAGE_NAME@" } )]
public class GcmBroadcastReceiver : GcmBroadcastReceiverBase<GcmService>
{
// Não precisa de nada aqui :)
}
}
Criar um Serviço que integre com o Notification Hub:
[Service]
public class GcmService : GcmServiceBase
{
private static NotificationHub hub;
public static void Initialize(Context context)
{
hub = new NotificationHub(PushNotificationConstants.HUB_NAME,
PushNotificationConstants.HUB_CONNECTION_STRING, context);
}
public static void Register(Context Context)
{
GcmClient.Register(Context, new[] { PushNotificationConstants.SENDER_ID } );
}
public GcmService() : base(new[] { PushNotificationConstants.SENDER_ID } )
{
}
// continua
…continuação
protected override void OnRegistered(Context context, string registrationId)
{
if (hub != null)
{
string[] tags = null; //pode especificar tags aqui
hub.Register(registrationId, tags);
}
}
protected override void OnUnRegistered(Context context, string registrationId)
{
if (hub != null)
{
hub.Unregister();
}
}
…continuação
protected override void OnMessage(Context context, Intent intent)
{
if (intent != null || intent.Extras != null)
{
foreach (var key in intent.Extras.KeySet())
{
// loga informações recebidas
Debug.WriteLine($"Key: {key} Value: {intent.Extras.Get(key)} ");
}
string message = intent.Extras.GetString("message");
if (!string.IsNullOrWhiteSpace(message))
{
CreateNotification("TDC 2017 - Notificação", message, intent.Extras);
return;
}
}
}
SIGNALR
http://signalr.net/
“ASP.NET SignalR is a new library for ASP.NET
developers that makes it incredibly simple to add real-time
web functionality to your applications. What is "real-time
web" functionality? It's the ability to have your server-side
code push content to the connected clients as it happens,
in real-time.”
• Serviço criado para hospedar um algoritmo de matchmaking que
armazena informações de Geolocalização, timestamp e informações
do usuário
• match = 2 usuários estarem no mesmo range de localização e no
mesmo range de tempo (10s de tolerância)
• Ao identificar um match o serviço SignalR envia informações trocadas
dos usuários
• ex: User1 e User2 são um match
• User 1 recebe informações de User2
• User2 recebe informações de User1
SIGNALR | REAL TIME COMMUNICATION
• Criar projeto asp.NET
• SignalR funciona em JS também, portanto você pode testar
usando sua própria View asp.Net MVC por exemplo
• Instalar dependência Microsoft.AspNet.SignalR
• Adicionar Startup.cs (boilerplate)
SIGNALR | Criando Serviço
public class Startup
{
public void Configuration(IAppBuilder app)
{
try
{
app.MapSignalR();
}
catch (Exception ex)
{
app.Run(async ctx => await ctx.Response.WriteAsync(ex.ToString()));
}
}
}
SIGNALR | Criando Serviço
public class MobileHub : Microsoft.AspNet.SignalR.Hub
{
//Qualquer método público pode ser chamado
public void ExchangeInformation(string deviceId, string message, string token)
{
//armazena informação recebida
StoredData.TryAdd(guid, new MobileInformation(Context.ConnectionId, deviceId, message, token));
//lógica de match
//. . .
Clients.Caller.OnInformationReceived(info.DeviceId, info.Message);
// Envia informação atual para os outros devices
Clients.Client(info.ConnectionId).OnInformationReceived(deviceId, message);
}
}
SIGNALR | Adicionando Hub
SIGNALR | Integração com Xamarin
public class SignalRClient
{
private const string URL = “https://url_do_seu_serviço_signalR”;
private const string HUB_NAME = "MobileHub";
private readonly HubConnection connection;
private readonly IHubProxy chatHubProxy;
public SignalRClient()
{
this.connection = new HubConnection(URL);
this.chatHubProxy = this.connection.CreateHubProxy(HUB_NAME);
this.chatHubProxy.On<string, string>(
“OnInformationReceived",
(deviceId, message) => {
// gerenciar informação recebida
} );
}
// continua
SIGNALR | Integração com Xamarin
//cria métodos para iniciar e parar o serviço pra serem gerenciados a parte
public Task Start()
{
Debug.WriteLine("Iniciando SignalR client");
return this.connection.Start();
}
public void Stop()
{
Debug.WriteLine("Parando SignalR client");
this.connection.Stop();
}
SIGNALR | Integração com Xamarin
public void SendMessage(string deviceId, string message, string token)
{
if (this.connection.State == ConnectionState.Connected)
{
// string tem que ser o nome do método declarado no
// serviço SignalR
this.chatHubProxy.Invoke("ExchangeInformation", deviceId, message, token);
}
}
SIGNALR | Integração com Xamarin
DEMO DO SAMPLE APP
XAMARIN + AZURE
VALE A PENA?
https://github.com/oberdanf/XamarinFormsAzure
https://github.com/oberdanf/XamarinFormsAzureServer
OBRIGADO.
Big Brains Wanted
Join our team! Go to arctouch.com/careers/

Mais conteúdo relacionado

Semelhante a Xamarin.Forms + Azure: Autenticação, Storage e Notificações

PDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETPDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETslides_teltools
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Elton Minetto
 
12 factor in the PHP world
12 factor in the PHP world12 factor in the PHP world
12 factor in the PHP worldElton Minetto
 
Work Cloud - Descobrindo o Microsoft Azure
Work Cloud - Descobrindo o Microsoft AzureWork Cloud - Descobrindo o Microsoft Azure
Work Cloud - Descobrindo o Microsoft AzureLucas Chies
 
Workshop Microservices - Microservices com Spring Cloud e Netflix OSS
Workshop Microservices - Microservices com Spring Cloud e Netflix OSSWorkshop Microservices - Microservices com Spring Cloud e Netflix OSS
Workshop Microservices - Microservices com Spring Cloud e Netflix OSSRodrigo Cândido da Silva
 
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...BrunoSouza617
 
The twelve factor apps and openruko
The twelve factor apps and openrukoThe twelve factor apps and openruko
The twelve factor apps and openrukoÉverton Ribeiro
 
TDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureTDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureDr. Spock
 
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDB
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDBFlask Full Stack - Desenvolvendo um CMS com Flask e MongoDB
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDBBruno Rocha
 
Backend as a Service - Firebase (Computação em Nuvem)
Backend as a Service - Firebase (Computação em Nuvem)Backend as a Service - Firebase (Computação em Nuvem)
Backend as a Service - Firebase (Computação em Nuvem)Jaderson Pedrossini
 
Notificações no iOS 10
Notificações no iOS 10Notificações no iOS 10
Notificações no iOS 10Rodrigo Borges
 
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWS
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWSAcelerando a entrega de software com as ferramentas de desenvolvimento da AWS
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWSAmazon Web Services LATAM
 
Analise frameworks php
Analise frameworks phpAnalise frameworks php
Analise frameworks phpIgor Moura
 
Ambiente de CI/CD com Google Cloud
Ambiente de CI/CD com Google CloudAmbiente de CI/CD com Google Cloud
Ambiente de CI/CD com Google CloudAlvaro Viebrantz
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeRafael Benevides
 
DevOps na AWS: Construindo Sistemas para Entregas Rápidas
DevOps na AWS: Construindo Sistemas para Entregas RápidasDevOps na AWS: Construindo Sistemas para Entregas Rápidas
DevOps na AWS: Construindo Sistemas para Entregas RápidasAmazon Web Services LATAM
 

Semelhante a Xamarin.Forms + Azure: Autenticação, Storage e Notificações (20)

Python 08
Python 08Python 08
Python 08
 
PDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETPDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NET
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2
 
12 factor in the PHP world
12 factor in the PHP world12 factor in the PHP world
12 factor in the PHP world
 
Work Cloud - Descobrindo o Microsoft Azure
Work Cloud - Descobrindo o Microsoft AzureWork Cloud - Descobrindo o Microsoft Azure
Work Cloud - Descobrindo o Microsoft Azure
 
Workshop Microservices - Microservices com Spring Cloud e Netflix OSS
Workshop Microservices - Microservices com Spring Cloud e Netflix OSSWorkshop Microservices - Microservices com Spring Cloud e Netflix OSS
Workshop Microservices - Microservices com Spring Cloud e Netflix OSS
 
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...
Symfony Live - São Paulo 2019 - Como construir uma API em um passo com API Pl...
 
The twelve factor apps and openruko
The twelve factor apps and openrukoThe twelve factor apps and openruko
The twelve factor apps and openruko
 
TDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureTDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & Azure
 
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDB
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDBFlask Full Stack - Desenvolvendo um CMS com Flask e MongoDB
Flask Full Stack - Desenvolvendo um CMS com Flask e MongoDB
 
Backend as a Service - Firebase (Computação em Nuvem)
Backend as a Service - Firebase (Computação em Nuvem)Backend as a Service - Firebase (Computação em Nuvem)
Backend as a Service - Firebase (Computação em Nuvem)
 
Notificações no iOS 10
Notificações no iOS 10Notificações no iOS 10
Notificações no iOS 10
 
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWS
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWSAcelerando a entrega de software com as ferramentas de desenvolvimento da AWS
Acelerando a entrega de software com as ferramentas de desenvolvimento da AWS
 
Meteor - TechParty 2015
Meteor - TechParty 2015Meteor - TechParty 2015
Meteor - TechParty 2015
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
 
Caelum Day In Rio
Caelum Day In RioCaelum Day In Rio
Caelum Day In Rio
 
Analise frameworks php
Analise frameworks phpAnalise frameworks php
Analise frameworks php
 
Ambiente de CI/CD com Google Cloud
Ambiente de CI/CD com Google CloudAmbiente de CI/CD com Google Cloud
Ambiente de CI/CD com Google Cloud
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpike
 
DevOps na AWS: Construindo Sistemas para Entregas Rápidas
DevOps na AWS: Construindo Sistemas para Entregas RápidasDevOps na AWS: Construindo Sistemas para Entregas Rápidas
DevOps na AWS: Construindo Sistemas para Entregas Rápidas
 

Mais de tdc-globalcode

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadetdc-globalcode
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...tdc-globalcode
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucessotdc-globalcode
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPAtdc-globalcode
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinotdc-globalcode
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...tdc-globalcode
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicestdc-globalcode
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publicatdc-globalcode
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#tdc-globalcode
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocustdc-globalcode
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?tdc-globalcode
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golangtdc-globalcode
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QAtdc-globalcode
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciatdc-globalcode
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Servicetdc-globalcode
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETtdc-globalcode
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8tdc-globalcode
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...tdc-globalcode
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#tdc-globalcode
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Coretdc-globalcode
 

Mais de tdc-globalcode (20)

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devices
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocus
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golang
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
 

Último

Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptx
Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptxSlides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptx
Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptxLuizHenriquedeAlmeid6
 
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestre
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestreCIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestre
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestreElianeElika
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...azulassessoria9
 
Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Ilda Bicacro
 
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdf
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdfENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdf
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdfLeloIurk1
 
Atividade - Letra da música Esperando na Janela.
Atividade -  Letra da música Esperando na Janela.Atividade -  Letra da música Esperando na Janela.
Atividade - Letra da música Esperando na Janela.Mary Alvarenga
 
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdf
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdfPROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdf
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdfMarianaMoraesMathias
 
Libras Jogo da memória em LIBRAS Memoria
Libras Jogo da memória em LIBRAS MemoriaLibras Jogo da memória em LIBRAS Memoria
Libras Jogo da memória em LIBRAS Memorialgrecchi
 
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptx
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptxJOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptx
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptxTainTorres4
 
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcante
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcanteCOMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcante
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcanteVanessaCavalcante37
 
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamentalAntônia marta Silvestre da Silva
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividadeMary Alvarenga
 
Bullying - Atividade com caça- palavras
Bullying   - Atividade com  caça- palavrasBullying   - Atividade com  caça- palavras
Bullying - Atividade com caça- palavrasMary Alvarenga
 
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de..."É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...Rosalina Simão Nunes
 
CRUZADINHA - Leitura e escrita dos números
CRUZADINHA   -   Leitura e escrita dos números CRUZADINHA   -   Leitura e escrita dos números
CRUZADINHA - Leitura e escrita dos números Mary Alvarenga
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...azulassessoria9
 
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕES
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕESCOMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕES
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕESEduardaReis50
 
VARIEDADES LINGUÍSTICAS - 1. pptx
VARIEDADES        LINGUÍSTICAS - 1. pptxVARIEDADES        LINGUÍSTICAS - 1. pptx
VARIEDADES LINGUÍSTICAS - 1. pptxMarlene Cunhada
 
Pedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxPedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxleandropereira983288
 

Último (20)

Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptx
Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptxSlides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptx
Slides Lição 04, Central Gospel, O Tribunal De Cristo, 1Tr24.pptx
 
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestre
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestreCIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestre
CIÊNCIAS HUMANAS - ENSINO MÉDIO. 2024 2 bimestre
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: COMUNICAÇÃO ASSERTIVA E INTERPESS...
 
Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!Rota das Ribeiras Camp, Projeto Nós Propomos!
Rota das Ribeiras Camp, Projeto Nós Propomos!
 
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdf
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdfENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdf
ENSINO RELIGIOSO 7º ANO INOVE NA ESCOLA.pdf
 
Atividade - Letra da música Esperando na Janela.
Atividade -  Letra da música Esperando na Janela.Atividade -  Letra da música Esperando na Janela.
Atividade - Letra da música Esperando na Janela.
 
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdf
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdfPROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdf
PROGRAMA DE AÇÃO 2024 - MARIANA DA SILVA MORAES.pdf
 
Libras Jogo da memória em LIBRAS Memoria
Libras Jogo da memória em LIBRAS MemoriaLibras Jogo da memória em LIBRAS Memoria
Libras Jogo da memória em LIBRAS Memoria
 
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptx
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptxJOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptx
JOGO FATO OU FAKE - ATIVIDADE LUDICA(1).pptx
 
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcante
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcanteCOMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcante
COMPETÊNCIA 2 da redação do enem prodção textual professora vanessa cavalcante
 
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental
2° ano_PLANO_DE_CURSO em PDF referente ao 2° ano do Ensino fundamental
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividade
 
Bullying - Atividade com caça- palavras
Bullying   - Atividade com  caça- palavrasBullying   - Atividade com  caça- palavras
Bullying - Atividade com caça- palavras
 
Bullying, sai pra lá
Bullying,  sai pra láBullying,  sai pra lá
Bullying, sai pra lá
 
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de..."É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...
"É melhor praticar para a nota" - Como avaliar comportamentos em contextos de...
 
CRUZADINHA - Leitura e escrita dos números
CRUZADINHA   -   Leitura e escrita dos números CRUZADINHA   -   Leitura e escrita dos números
CRUZADINHA - Leitura e escrita dos números
 
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...
PROVA - ESTUDO CONTEMPORÂNEO E TRANSVERSAL: LEITURA DE IMAGENS, GRÁFICOS E MA...
 
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕES
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕESCOMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕES
COMPETÊNCIA 4 NO ENEM: O TEXTO E SUAS AMARRACÕES
 
VARIEDADES LINGUÍSTICAS - 1. pptx
VARIEDADES        LINGUÍSTICAS - 1. pptxVARIEDADES        LINGUÍSTICAS - 1. pptx
VARIEDADES LINGUÍSTICAS - 1. pptx
 
Pedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxPedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptx
 

Xamarin.Forms + Azure: Autenticação, Storage e Notificações

  • 1. 11 XAMARIN.FORMS + AZURE: UM ESTUDO DE CASO Oberdan Ferreira
  • 2. 22 XAMARIN.FORMS + AZURE: UM ESTUDO DE CASO Oberdan Ferreira
  • 3. SOBRE MIM | Oberdan Ferreira Principal Engineer @ArcTouch @oberdanferreira oberdan.bitencourt@gmail.com
  • 4. • INTRODUÇÃO • AUTENTICAÇÃO COM AZURE ACTIVE DIRECTORY • INTEGRAÇÃO COM AZURE STORAGE • BLOB • QUEUE • AZURE NOTIFICATIONS HUB (PUSH NOTIFICATIONS) • COMUNICAÇÃO EM TEMPO REAL COM SIGNALR AGENDA
  • 5. • Grey Global Group • Uma agência global de marketing e propaganda • Utiliza serviços Microsoft (AD, API Apps, DocumentDb, etc.) • Bancos de dados mantém dados legados • A Grey emprega mais de 1500 funcionários. INTRODUÇÃO | ESTUDO DE CASO - GREY
  • 6. • Como surgiu a ideia do app? • Necessidade de conectar seus funcionários com colegas de trabalho • Atualizar funcionários com notícias sobre a empresa • Alertá-los sobre eventos que estão para ocorrer INTRODUÇÃO | ESTUDO DE CASO - GREY
  • 7. • Backend Microsoft • Active Directory • API Apps no Azure INTRODUÇÃO | ESTUDO DE CASO - GREY =
  • 9. • Possibilita login no app por qualquer funcionário da empresa com baixo esforço. • Autenticação gerenciada pela Microsoft • Autenticação Cross Platform (Android, iOS) • Refresh de OAuth token é automático • Compartilhar token p/ chamadas a API AUTENTICAÇÃO | ADAL - PRÓS
  • 10. • Autenticação gerenciada pela Microsoft - pouca customização. • Cliente não entende que não dá pra trocar o layout da webview. • Trocar Profile da PCL para usar as versões mais atuais • v. 3.13.19 - PCL7 (sem Windows 8.1 ou 10) • Exige configuração no lado do servidor para autorizar o token via Azure Portal. • Na época o AD era gerenciado via manage.windowsazure.com • APIs hospedadas em portal.azure.com AUTENTICAÇÃO | ADAL - CONTRAS
  • 11. AUTENTICAÇÃO | ADAL - Criar App no AD
  • 13. AZURE STORAGE | Integração com Xamarin
  • 14. private async Task<AuthenticationResult> Authenticate(string authority, string resource, string clientId, string returnUri) { var authContext = new AuthenticationContext(authority); var authResult = await authContext .AcquireTokenAsync( resource, //https://login.microsoftonline.com/common clientId, //valor registrado no Azure uri, //valor registrado no Azure PlatformAuthenticator.PlatformParameters); //Pego via DependencyService. //Android: new PlatformParameters((Activity)Forms.Context) //iOS: new PlatformParameters(UIApplication .SharedApplication .KeyWindow .RootViewController); return authResult; // contém informações básicas do usuário logado e OAuth token }
  • 15. AZURE STORAGE | Integração com Xamarin
  • 17. AZURE STORAGE | Overview • Permite hospedagem de arquivos (imagens, documentos, etc), mensagens, tabelas • Arquivos somente podem ser acessados por meio de um Shared Access Token • Mensagens podem ser enfileiradas com confiabilidade • Redundância de dados nos servidores espalhados pelo mundo • Consistência dos dados (garantir que sempre a última versão será utilizada)
  • 18. AZURE STORAGE | BLOB - Utilização no App • Utilizado para salvar fotos de perfil dos funcionários • Imagens enviadas para um Blob Storage • Blob é lido por um job controlado pelo cliente • Imagem é atualizada no banco de dados do cliente (inacessível por nós) • API de pessoas retornava a foto de perfil apontando para o Azure
  • 19. AZURE STORAGE | QUEUE - Utilização no App • Queue utilizada para atualizar preferências do app para cada funcionário • Mensagem enviada em formato JSON • Queue é lida por um Azure Job controlado pelo cliente • Job atualiza o backend do cliente • Problema: demora cerca de 4 minutos para a informação ser processada (provavelmente por configuração/performance do lado do cliente)
  • 21. AZURE STORAGE | Integração com Xamarin
  • 22. • Últimas versões rodam no .NET Standard (e instalam uma porrada de dependências) • Falha ao instalar System.Runtime.InteropServices.RuntimeInformation.4.0.0 • Dica: Instale o System.Runtime.InteropServices.RuntimeInformation4.3.0 antes! AZURE STORAGE | Integração com Xamarin
  • 23. PCL COM XAMARIN.FORMS .RUNTIMEINFORMATION
  • 24. PCL COM XAMARIN.FORMS + WINDOWSAZURE.STORAGE V8.1.1
  • 25. SHOW ME THE CODE BLOB
  • 26. const string STORAGE_IMAGE_BLOB = "tdc-blob"; const string STORAGE_CONNECTION_STRING = “DefaultEndpointsProtocol=https;AccountName=tdc;AccountKey……”; private CloudBlobContainer GetContainer() { // configura a conta var account = CloudStorageAccount.Parse(STORAGE_CONNECTION_STRING); // cria um blob client var client = account.CreateCloudBlobClient(); // pega o contêiner criado no Azure var container = client.GetContainerReference(STORAGE_IMAGE_BLOB); return container; }
  • 27. public async Task<string> UploadImageAsync(Stream image) { var container = GetContainer(); // tenta criar contêiner se ele não existir await container.CreateIfNotExistsAsync(); var name = $"{Guid.NewGuid().ToString("D")}.jpg"; // cria uma referência de Blob para salvar o arquivo var imageBlob = container.GetBlockBlobReference(name); // faz o upload assíncrono do stream await imageBlob.UploadFromStreamAsync(image); // retorna o novo nome do arquivo para // fazer o download no futuro return name; }
  • 28. public async Task<byte[]> GetImageAsync(string name) { // pega o contêiner var container = GetContainer(); // pega referência pra imagem pelo nomo do arquivo var blob = container.GetBlobReference(name); if (await blob.ExistsAsync()) { // se existir, pega os atributos await blob.FetchAttributesAsync(); byte[] blobBytes = new byte[blob.Properties.Length]; // faz download do byte array await blob.DownloadToByteArrayAsync(blobBytes, 0); return blobBytes; } return null; }
  • 29. SHOW ME THE CODE QUEUE
  • 30. public async Task AddMessageAsync(string message) { try { var cloudQueue = GetCloudQueue(); // cria fila caso não exista await cloudQueue.CreateIfNotExistsAsync(); // envia mensagem pra fila await cloudQueue.AddMessageAsync( new CloudQueueMessage(message)); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } }
  • 31. public async Task<string> GetLastMessageAsync() { try { var cloudQueue = GetCloudQueue(); await cloudQueue.CreateIfNotExistsAsync(); // lê mensagem da fila CloudQueueMessage queue = await cloudQueue.GetMessageAsync(); // remove mensagem lida await cloudQueue.DeleteMessageAsync(queue); // retorna como string return queue.AsString; } catch (Exception ex) { … }
  • 33. • Push Notifications utilizados para alertar usuários sobre novas notícias, alertar sobre eventos • Backend integra com Azure e disparava os push notifications NOTIFICATION HUBS | Utilização no app
  • 34. • Possibilita enviar Push Notifications para várias plataformas (iOS, Android, Windows, Kindle e Baidu) • SDK em .NET, Node.JS, Java e PHP • Push Notifications direcionados com tags • Grátis até 1 milhão de Push Notifications enviados AZURE | Notification Hubs
  • 35. • Gerar um Certificate Signing Request File na sua máquina • Ir até developer.apple.com • Criar certificado de Push Notification com base no CSR criado na sua máquina • Baixar o .cer e instalar na sua máquina • Abrir o Keychain Access no macOS e exportar o certificado em formato .p12 • Criar um Provisioning Profile em developer.apple.com usando o .p12 • Incluir os devices registrados no Provisioning Profile (você não pode distribuir o app para qualquer device) • Gerar, baixar e instalar o Provisioning Profile NOTIFICATION HUBS | IOS
  • 37. NOTIFICATION HUBS | Criando NotificationHub
  • 38. NOTIFICATION HUBS | Integração com Xamarin
  • 39. NOTIFICATION HUBS | Integração com Xamarin
  • 40. IOS
  • 41. public override bool FinishedLaunching(UIApplication app, NSDictionary options) { // Gerencia notificações recebidas com app fechado ao // abrir ProcessNotification(options); // Registra para receber notificações // Popup vai aparecer para o usuário UIApplication.SharedApplication.RegisterForRemoteNotificationTypes( UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound); ... }
  • 42. public override void RegisteredForRemoteNotifications(UIApplication app, NSData deviceToken) { // Cria conexão com Azure Notification Hub // Pegar parâmetros no Azure Portal var cs = SBConnectionString.CreateListenAccess( new NSUrl("sb://seuservicebus-ns.servicebus.windows.net/"), "SUA-KEY"); // Registrar device no azure var hub = new SBNotificationHub(cs, "seu-hub-name"); hub.RegisterNativeAsync(deviceToken, null, err => { if (err != null) Console.WriteLine("Erro: " + err.Description); else Console.WriteLine($”Sucesson Token: {deviceToken}“); }); }
  • 43. public override void ReceivedRemoteNotification(UIApplication app, NSDictionary userInfo) { // Processa a notificação recebida com o app aberto // Iterar sobre o userInfo e processar a informação recebida // ex.: navegar para uma página ProcessNotification(userInfo); }
  • 45. No AssemblyInfo.cs do projeto Droid adicionar: // Permissão que notifica o app que o device terminou de ligar [assembly: UsesPermission(Android.Manifest.Permission.ReceiveBootCompleted)]
  • 46. Criar um BroadcastReceiver: [assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")] [assembly: UsesPermission(Name = "android.permission.INTERNET")] [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] namespace XamarinFormsAzure.Droid { [BroadcastReceiver(Permission = Gcm.Constants.PERMISSION_GCM_INTENTS)] [IntentFilter(new[] { Intent.ActionBootCompleted } )] // Permite gerenciar push com app fechado [IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_MESSAGE }, Categories = new[] { "@PACKAGE_NAME@" } )] [IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new[] { "@PACKAGE_NAME@" } )] [IntentFilter(new[] { Gcm.Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new[] { "@PACKAGE_NAME@" } )] [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" }, Categories = new[] { "@PACKAGE_NAME@" } )] public class GcmBroadcastReceiver : GcmBroadcastReceiverBase<GcmService> { // Não precisa de nada aqui :) } }
  • 47. Criar um Serviço que integre com o Notification Hub: [Service] public class GcmService : GcmServiceBase { private static NotificationHub hub; public static void Initialize(Context context) { hub = new NotificationHub(PushNotificationConstants.HUB_NAME, PushNotificationConstants.HUB_CONNECTION_STRING, context); } public static void Register(Context Context) { GcmClient.Register(Context, new[] { PushNotificationConstants.SENDER_ID } ); } public GcmService() : base(new[] { PushNotificationConstants.SENDER_ID } ) { } // continua
  • 48. …continuação protected override void OnRegistered(Context context, string registrationId) { if (hub != null) { string[] tags = null; //pode especificar tags aqui hub.Register(registrationId, tags); } } protected override void OnUnRegistered(Context context, string registrationId) { if (hub != null) { hub.Unregister(); } }
  • 49. …continuação protected override void OnMessage(Context context, Intent intent) { if (intent != null || intent.Extras != null) { foreach (var key in intent.Extras.KeySet()) { // loga informações recebidas Debug.WriteLine($"Key: {key} Value: {intent.Extras.Get(key)} "); } string message = intent.Extras.GetString("message"); if (!string.IsNullOrWhiteSpace(message)) { CreateNotification("TDC 2017 - Notificação", message, intent.Extras); return; } } }
  • 51. http://signalr.net/ “ASP.NET SignalR is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. What is "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time.”
  • 52. • Serviço criado para hospedar um algoritmo de matchmaking que armazena informações de Geolocalização, timestamp e informações do usuário • match = 2 usuários estarem no mesmo range de localização e no mesmo range de tempo (10s de tolerância) • Ao identificar um match o serviço SignalR envia informações trocadas dos usuários • ex: User1 e User2 são um match • User 1 recebe informações de User2 • User2 recebe informações de User1 SIGNALR | REAL TIME COMMUNICATION
  • 53. • Criar projeto asp.NET • SignalR funciona em JS também, portanto você pode testar usando sua própria View asp.Net MVC por exemplo • Instalar dependência Microsoft.AspNet.SignalR • Adicionar Startup.cs (boilerplate) SIGNALR | Criando Serviço
  • 54. public class Startup { public void Configuration(IAppBuilder app) { try { app.MapSignalR(); } catch (Exception ex) { app.Run(async ctx => await ctx.Response.WriteAsync(ex.ToString())); } } } SIGNALR | Criando Serviço
  • 55. public class MobileHub : Microsoft.AspNet.SignalR.Hub { //Qualquer método público pode ser chamado public void ExchangeInformation(string deviceId, string message, string token) { //armazena informação recebida StoredData.TryAdd(guid, new MobileInformation(Context.ConnectionId, deviceId, message, token)); //lógica de match //. . . Clients.Caller.OnInformationReceived(info.DeviceId, info.Message); // Envia informação atual para os outros devices Clients.Client(info.ConnectionId).OnInformationReceived(deviceId, message); } } SIGNALR | Adicionando Hub
  • 56. SIGNALR | Integração com Xamarin
  • 57. public class SignalRClient { private const string URL = “https://url_do_seu_serviço_signalR”; private const string HUB_NAME = "MobileHub"; private readonly HubConnection connection; private readonly IHubProxy chatHubProxy; public SignalRClient() { this.connection = new HubConnection(URL); this.chatHubProxy = this.connection.CreateHubProxy(HUB_NAME); this.chatHubProxy.On<string, string>( “OnInformationReceived", (deviceId, message) => { // gerenciar informação recebida } ); } // continua SIGNALR | Integração com Xamarin
  • 58. //cria métodos para iniciar e parar o serviço pra serem gerenciados a parte public Task Start() { Debug.WriteLine("Iniciando SignalR client"); return this.connection.Start(); } public void Stop() { Debug.WriteLine("Parando SignalR client"); this.connection.Stop(); } SIGNALR | Integração com Xamarin
  • 59. public void SendMessage(string deviceId, string message, string token) { if (this.connection.State == ConnectionState.Connected) { // string tem que ser o nome do método declarado no // serviço SignalR this.chatHubProxy.Invoke("ExchangeInformation", deviceId, message, token); } } SIGNALR | Integração com Xamarin
  • 61.
  • 64. OBRIGADO. Big Brains Wanted Join our team! Go to arctouch.com/careers/