;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Guilherme Rambo

ANÁLISE

Texto baseado no relato de acontecimentos, mas contextualizado a partir do conhecimento do jornalista sobre o tema; pode incluir interpretações do jornalista sobre os fatos.

Não é tão simples: Apple tem muitos desafios para incluir Face ID no Mac

Divulgação/ Apple
Imagem: Divulgação/ Apple

30/07/2021 04h00

O Face ID foi introduzido em 2017 com o lançamento do iPhone X. Na época, a tecnologia serviu para tornar possível a criação de um iPhone sem o botão Home, existente desde a primeira versão do aparelho, lançada dez anos antes. Além de melhorar a segurança com relação ao Touch ID, o Face ID incluiu também o sistema de câmeras TrueDepth, capaz de interpretar expressões faciais, trazendo consigo recursos como fotos em modo retrato e animoji/memoji.

Atualmente, a tecnologia está presente em diversos iPhones e iPads na linha de produtos da Apple. Com a pandemia e as pessoas usando máscara, acabou se tornando um inconveniente, o que fez muita gente questionar a validade da tecnologia e clamar pela volta do sensor de impressão digital. A empresa entregou uma solução através do desbloqueio via Apple Watch — mas isso requer um dispositivo extra, claro.

comentei por aqui que no meu mundo ideal, o iPhone teria as duas opções — Face ID e Touch ID ao mesmo tempo — para que o usuário escolhesse qual mecanismo de autenticação deseja usar dependendo do contexto. Está de máscara ou não consegue olhar para a tela do iPhone? Vai de Touch ID. Está com os dedos molhados ou com as mãos ocupadas? Face ID.

Discussões sobre preferências à parte, existe uma linha de produtos da Apple que ainda não foi contemplada com o recurso: a linha de Macs. Antes da introdução dos Macs com processadores da Apple, existiu muita especulação sobre se eles viriam com Face ID. Pois a Apple lançou já quatro modelos de Macs com o processador M1 e nenhum deles conta com a tecnologia.

Recentemente, o analista Mark Gurman afirmou que a Apple estaria sim trabalhando para trazer o recurso aos Macs, mas que isso ainda levaria algum tempo — um ou dois anos, segundo ele.

Essa linha do tempo pode parecer surpreendentemente longa para algumas pessoas que querem o recurso no Mac, mas eu entendo perfeitamente o motivo dessa demora, que se dá por conta de alguns fatores.

O primeiro fator é sobre usabilidade. A conveniência do Face ID no Mac não seria tão maior quando comparada à conveniência do Touch ID, já presente em diversos modelos.

O desbloqueio do Mac é feito com menos frequência que no iPhone ou iPad. Além disso, quando é preciso autenticar alguma ação ou transação no computador, as mãos do usuário geralmente já se encontram no teclado, que é onde fica o sensor de impressão digital, então acaba sendo um gesto simples e cômodo de ser executado.

Em Macs que não possuem Touch ID — como o Mac Mini M1 que eu utilizo aqui — a autenticação via Apple Watch dá conta do recado, ela é tão boa que às vezes parece que o Mac nem tem senha de bloqueio (mesma sensação que eu tive ao usar o Face ID no iPhone X pela primeira vez).

Levando em conta este contexto, é fácil compreender o porquê do Face ID no Mac não ter sido priorizado pela Apple até o momento.

Além dessa questão, existem também alguns desafios técnicos que precisam de solução para tornar o Face ID no Mac possível.

Se você possui um Mac portátil, olhe bem para a espessura da tela, incluindo a tampa traseira. Agora compare essa espessura com a espessura de um iPhone. Muita gente vê o sistema TrueDepth na frente do iPhone e imagina que ele é muito fino e ocupa apenas a parte frontal do aparelho, mas na verdade o sistema é montado na parte de trás do iPhone e se estende até a frente, onde ficam as lentes. Não haveria espaço para incluir esse sensor em nenhum dos Macs portáteis atuais.

Existe também outra questão técnica quando o assunto envolve pagamentos e outras operações que requerem confirmação do usuário.

No iPhone e no iPad, quando o Face ID é usado para autenticar um pagamento —seja virtual ou físico— existe um o a mais: o usuário precisa dar dois cliques no botão lateral para confirmar sua intenção. Essa confirmação não ocorre em software, o botão lateral está diretamente ligado ao Secure Enclave do aparelho, responsável pelas operações de segurança e pagamentos.

Não existe um botão equivalente nos Macs que poderia ser usado para o mesmo fim. A Apple precisaria incluir um botão assim, ou implementar a mesma funcionalidade com um botão do teclado já existente. Ainda assim, existe o desafio de como isso funcionaria em Macs nos quais o usuário pode utilizar um teclado externo — iMacs, por exemplo.

Mas será que a Apple não poderia simplesmente mostrar um botão na tela para o usuário clicar, confirmando a intenção de pagamento? A resposta é não. Esse tipo de confirmação precisa ter um componente de hardware envolvido, para evitar que um comprometimento do software possa ser usado para forçar o usuário a pagar por alguma coisa.

Apesar dessas questões, acredito sim que veremos o Face ID nos Macs num futuro não tão distante. Além de permitir a autenticação, a presença do sistema TrueDepth permitiria recursos como o Center Stage que veio nos novos iPads Pro, dentre outros recursos de realidade aumentada.