Mobile Services 
Ivan Paulovich | MVP ASP.NET 
http://www.100loop.com
Ivan Paulovich
Mobile Services 
• Monitoramento e gerenciamento 24x7 
• SSO com Active Directory, Facebook, Twitter, e Google 
• Push notifications 
• Dados em SQL, Table Storage, e MongoDB 
• Consome Office 365 e SharePoint 
• Apps offline podem sincronizar com a núvem
Principais Componentes 
Envio de Notificações 
Lógica no Servidor 
Autenticação e Autorização Armazenamento de Dados 
Agendamento de Tarefas 
Logs e Diagnósticos 
Escalabilidade
Introdução ao Mobile Services 
• Apresentação do Painel de Gerenciamento 
• https://manage.windowsazure.com/ 
• Criação de tabelas 
• Download de exemplos de códigos
Demo
Autenticação e Autorização 
• Autenticação integrada a provedores 
• Autorização granular
Demo
Tarefas Agendadas
Demo
Chamar método de uma API
Integração com Git
Demo
Scripts de Servidor
Demo
Referências 
SDKs 
http://azure.microsoft.com/en-us/downloads/ 
Documentação do Mobile Services em Português 
http://azure.microsoft.com/pt-br/documentation/services/mobile-services/
Obrigado! 
http://fb.com/ivan.paulovich @ivanpaulovich 
ivan@100loop.com http://www.100loop.com

Windows Azure Mobile Services InfoTech 2014

Notas do Editor

  • #9 http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-get-started/
  • #13 http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-get-started-users/ ------------------ <div id="logged-in"> Você está conectado como <span id="login-name"></span>. <button id="log-out">Fazer logoff</button> </div> <div id="logged-out"> Você não está conectado. <button>Fazer Logon</button> </div> ------------------ function refreshAuthDisplay() { var isLoggedIn = client.currentUser !== null; $("#logged-in").toggle(isLoggedIn); $("#logged-out").toggle(!isLoggedIn); if (isLoggedIn) { $("#login-name").text(client.currentUser.userId); refreshTodoItems(); } } function logIn() { client.login("facebook").then(refreshAuthDisplay, function(error){ alert(error); }); } function logOut() { client.logout(); refreshAuthDisplay(); $('#summary').html('<strong>You must login to access data.</strong>'); } // On page init, fetch the data and set up event handlers $(function () { refreshAuthDisplay(); $('#summary').html('<strong>You must login to access data.</strong>'); $("#logged-out button").click(logIn); $("#logged-in button").click(logOut); });
  • #17 var updatesTable = tables.getTable('Updates'); var request = require('request'); var twitterUrl = "https://api.twitter.com/1.1/search/tweets.json?q=DebateNaRecord&result_type=recent"; // Get the service configuration module. var config = require('mobileservice-config'); // Get the stored Twitter consumer key and secret. var consumerKey = config.twitterConsumerKey, consumerSecret = config.twitterConsumerSecret // Get the Twitter access token from app settings. var accessToken= config.appSettings.TWITTER_ACCESS_TOKEN, accessTokenSecret = config.appSettings.TWITTER_ACCESS_TOKEN_SECRET; function GetUpdates() { // Check what is the last tweet we stored when the job last ran // and ask Twitter to only give us more recent tweets appendLastTweetId( twitterUrl, function twitterUrlReady(url){ // Create a new request with OAuth credentials. request.get({ url: url, oauth: { consumer_key: consumerKey, consumer_secret: consumerSecret, token: accessToken, token_secret: accessTokenSecret }}, function (error, response, body) { if (!error && response.statusCode == 200) { var results = JSON.parse(body).statuses; if(results){ console.log('Fetched ' + results.length + ' new results from Twitter'); results.forEach(function (tweet){ if(!filterOutTweet(tweet)){ var update = { twitterId: tweet.id, text: tweet.text, author: tweet.user.screen_name, date: tweet.created_at }; updatesTable.insert(update); } }); } } else { console.error('Could not contact Twitter'); } }); }); } // Find the largest (most recent) tweet ID we have already stored // (if we have stored any) and ask Twitter to only return more // recent ones function appendLastTweetId(url, callback){ updatesTable .orderByDescending('twitterId') .read({success: function readUpdates(updates){ if(updates.length){ callback(url + '&since_id=' + (updates[0].twitterId + 1)); } else { callback(url); } }}); } function filterOutTweet(tweet){ // Remove retweets and replies return (tweet.text.indexOf('RT') === 0 || tweet.to_user_id); }
  • #19 http://azure.microsoft.com/pt-br/documentation/articles/mobile-services-html-call-custom-api/ exports.post = function(request, response) { var mssql = request.service.mssql; var sql = "UPDATE todoitem SET complete = 1 " + "WHERE complete = 0; SELECT @@ROWCOUNT as count"; mssql.query(sql, { success: function(results) { if(results.length == 1) response.send(200, results[0]); } }) }; exports.get = function(request, response) { response.send(statusCodes.OK, { message : 'Hello World!' }); }; <button id="buttonCompleteAll">Complete All</button> var completeAllTodoItems = function () { // Asynchronously call the custom API using the POST method. client.invokeApi("completeall", { body: null, method: "post" }).done(function (results) { var message = results.result.count + " item(s) marked as complete."; alert(message); refreshTodoItems(); }, function(error) { alert(error.message); }); }; $('#buttonCompleteAll').click(function () { completeAllTodoItems(); });
  • #26 https://code.msdn.microsoft.com/windowsapps/Capture-Store-and-Email-34005240
  • #29 var SendGrid = require('sendgrid').SendGrid; function insert(item, user, request) { request.execute({ success: function() { // After the record has been inserted, send the response immediately to the client request.respond(); // Send the email in the background sendEmail(item); } }); function sendEmail(item) { var sendgrid = new SendGrid('azure_f043f759701e2a9c5c21b90ef0c3b703@azure.com', 'yhtmFS0wS69jQ59'); sendgrid.send({ to: 'ivan@100loop.com', from: 'admin@todoitem.com', subject: 'New to-do item', text: 'A new to-do was added: ' + item.text }, function(success, message) { // If the email failed to send, log it as an error so we can investigate if (!success) { console.error(message); } }); } }
  • #31 http://azure.microsoft.com/pt-br/documentation/articles/mobile-services-html-call-custom-api/ <button id="buttonCompleteAll">Complete All</button> var completeAllTodoItems = function () { // Asynchronously call the custom API using the POST method. client.invokeApi("completeall", { body: null, method: "post" }).done(function (results) { var message = results.result.count + " item(s) marked as complete."; alert(message); refreshTodoItems(); }, function(error) { alert(error.message); }); }; $('#buttonCompleteAll').click(function () { completeAllTodoItems(); });