Skip to content

Commit 0a3eb96

Browse files
authored
Merge pull request #24 from loloop/mauricio/image-modifier
adds first pass for markdown image modifier
2 parents d94e803 + 69d1968 commit 0a3eb96

6 files changed

Lines changed: 50 additions & 19 deletions

File tree

site/Content/br/appclips.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Os App Clips tem um tamanho limite de 10MB por Clip, então é importante escolh
1616

1717
Começando do começo, os App Clips são um app como qualquer outro, apenas com algumas limitações, então para criá-los é bem simples, basta criar um target novo no seu projeto com o App Clip desejado. Como é possível criar mais de um clip por app, é interessante utilizar um bundle identifier que vai representar a funcionalidade do seu clip. Não se preocupe muito com isso, porque dá pra criar e configurar outros depois :) No app da NSBrazil, criei como `com.cocoaheads.conf.baseClip`
1818

19-
![](/images/appclips/creating-clip-target.png)
19+
![](appclips/creating-clip-target.png)
2020

2121
Uma das coisas mais legais dos App Clips é que eles são obrigatoriamente apps de iOS 14+, então nós podemos usar o lifecycle de um app SwiftUI ao invés do clássico App/SceneDelegate do UIKit. Também é possível usar eles, claro, mas se a gente pode optar pelo processo mais simples, por que não?
2222

@@ -75,7 +75,7 @@ No clip da NSBrazil, existe uma `View` que só existe dentro do código do App C
7575

7676
Escolhendo esse approach de compilar os mesmos arquivos para targets diferentes, as vezes ainda precisamos fazer alterações específicas para a experiência do nosso clip. Para esses casos, podemos criar uma compiler flag que vai incluir o código apenas na compilação do clip, em `Swift Compiler - Custom Flags` do target do App Clip, adicionando a `-D <NOMEDASUAFLAG>`:
7777

78-
![](/images/appclips/swiftflag.png)
78+
![](appclips/swiftflag.png)
7979

8080
Com isso, podemos escrever nosso código incluindo as flags quando necessário, como por exemplo:
8181

@@ -106,29 +106,29 @@ VStack(alignment: .leading, spacing: 5) {
106106

107107
E aí, compilando tanto o app quanto o App Clip, podemos ver o resultado:
108108

109-
![](/images/appclips/clipcomparison.png)
109+
![](appclips/clipcomparison.png)
110110

111111
## Invocando e testando o App Clip
112112

113113
Com o nosso código pronto e organizado, agora precisamos testar o clip. Rodando pelo Xcode, o clip se comporta com o mesmo processo de um app comum no simulador, mas essa não é a experiência completa que o usuário vai ter quando for invocar o clip, não é? Para isso, precisamos associar o domínio da URL que usaremos para invocar nas capabilities do target do clip:
114114

115-
![](/images/appclips/assoc-domains.png)
115+
![](appclips/assoc-domains.png)
116116

117117
E também precisamos criar uma Local Experience no menu de Desenvolvedor (`Desenvolvedor -> Local Experiences -> Register Local Experience`) do aparelho:
118118

119-
![](/images/appclips/local-experience.png)
119+
![](appclips/local-experience.png)
120120

121121
<p class="center muted caption">Caso o menu Desenvolvedor não esteja aparecendo nos Ajustes, instale um app no seu device pelo Xcode</p>
122122

123123
Assim que esse menu for preenchido, podemos abrir a câmera ou o Scanner de códigos do sistema e testar o nosso App Clip!
124124

125125
Caso queira testar em outros devices, é possível arquivar uma versão para instalação *ad-hoc* ou subir o app para o `TestFlight`, e aí, só seguir os mesmos passos de criar a experiência local.
126126

127-
![](/images/appclips/testflight.png)
127+
![](appclips/testflight.png)
128128

129129
Uma das limitações mais importantes do App Clip é o tamanho do app, e é bem fácil da gente checar isso também, basta arquivar o App Clip para instalações *ad-hoc* e marcar essas opções:
130130

131-
![](/images/appclips/thinning.png)
131+
![](appclips/thinning.png)
132132

133133
Dentro da pasta que o Xcode criou pra gente, existe um arquivo chamado `App Thinning Size Report.txt`, com o tamanho do seu clip para cada variante do App Thinning. Procure pela variante `Universal` do app e verifique o tamanho **uncompressed** dela. Esse é o tamanho que não pode passar de 10MB.
134134

@@ -196,6 +196,6 @@ A partir daí, podemos criar as imagens de acesso, que podem ser tanto um QR Cod
196196

197197
O último passo é criar a experiência no AppStore Connect, preencher todos os detalhes para formar o card do clip, e esperar até 48h para que ele se propague. (OBS: Essa parte só vai aparecer no seu Connect depois que você subir um build que contém um App Clip)
198198

199-
![](/images/appclips/appstore.png)
199+
![](appclips/appstore.png)
200200

201201
E é isso! Nosso App Clip está pronto para ser compartilhado com o mundo. Se você quiser conferir o projeto completo do app da NSBrazil, é só entrar lá no [Repositório do Projeto](https://github.com/CocoaHeadsConference/CHConferenceApp), completamente feito com SwiftUI, com target a partir do iOS13!

site/Content/br/event-based-architechture-for-spritekit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ O SpriteKit é um framework desenvolvido pela Apple para a criação de jogos de
1414

1515
O jogo de exemplo que desenvolvi para expor esta arquitetura é um infinite runner bem simples, que conta com todos os elementos básicos que se espera de um jogo: uma personagem que tem movimentos, ações, animações, pontos de vida, sons, que existe em um ambiente animado com inimigos que reagem a personagem e tentam acabar com a existência dela, e claro, com uma boa trilha sonora de fundo também.
1616

17-
![](/images/spritekit/game.jpeg)
17+
![](spritekit/game.jpeg)
1818
<p class="center muted caption">Toda a arte deste jogo é composta de assets de domínio público, criados pelo ótimo <a href="https://kenney.nl">Kenney</a></p>
1919

2020
O objeto básico do SpriteKit é o `SKNode`, todos os objetos que vão ser utilizados no contexto dele são do mesmo tipo, e quando juntos, formam uma árvore de nós pais e filhos, com métodos prontos para acessá-los.

site/Content/br/serversideswift.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@ Escrever o código todos nós já entendemos bem, e ver o resultado da nossa cri
1616

1717
Eu criei o [@F1LandinhoBot](https://t.me/F1LandinhoBot) com o intuito de me ajudar a lembrar os horários das corridas da Fórmula 1 num grupo de amigos, acessando a API do Telegram e mandando mensagens para que a gente não perdesse o horário de uma sessão sequer das corridas.
1818

19-
![](/images/serverswift/telegram.png)
19+
![](serverswift/telegram.png)
2020

2121
E funcionou tudo bem tranquilo rodando direto no meu Mac, mas eu não quero deixar o meu Mac ligado o tempo todo, rodando esse código pro bot funcionar, e não quero nem pensar em como eu vou garantir que ele vai funcionar o tempo todo. Onde moro, quedas de energia são bem comuns, e isso me parece um desperdício de processamento do meu computador de qualquer forma.
2222

2323
Então resolvi colocar esse código para rodar no meu servidor na Amazon, que eu já tenho faz uns anos rodando um [servidor de Quake](https://quake.host), então não precisaria desembolsar nenhum centavo a mais do que eu já pago por ele pra colocar o serviço no ar. O setup do Swift no Linux está todo detalhado no [Swift.org](https://swift.org) e apesar de um pouco trabalhoso, é fácil de seguir. Clonei o código do GitHub e eu não estava esperando o que vinha a seguir:
2424

25-
![](/images/serverswift/wont-build.png)
25+
![](serverswift/wont-build.png)
2626
<p class="center muted caption">OpenCombine é uma biblioteca feita especificamente pra gente usar o Combine no Linux, como assim ela não existe? Desde quando URLSession é um AnyObject?</p>
2727

2828
## Swift no Linux
2929

3030
Existem algumas lombadas durante o caminho do Swift no servidor que são raramente mencionadas, principalmente porque são abstraídas pelos frameworks famosos, mas que você vai encontrar bem rápido se for pelo caminho de escrever o código "puro". Todas elas existem por conta do fato de que o Swift no Mac não traz as mesmas bibliotecas que o Swift no Linux. O Foundation, que a gente está bastante acostumado a usar no mundo Apple não é o mesmo Foundation que existe no Linux, e isso [não é documentado](https://forums.swift.org/t/what-are-best-practices-to-write-a-linux-software-on-macos/) em lugar algum. É um problema que [não deve durar muito tempo](https://www.swift.org/blog/future-of-foundation/), mas ainda é um problema.
3131

32-
![](/images/serverswift/urlsession.png)
32+
![](serverswift/urlsession.png)
3333
<p class="center muted caption">O URLSession fica em uma biblioteca completamente diferente no Linux, que nem existe no macOS!</p>
3434

3535
## Publicando o nosso trabalho
@@ -110,6 +110,6 @@ E é isso! Desse jeito você consegue automatizar a execução do seu código em
110110

111111
Um jeito muito mais fácil de se realizar esse processo todo é utilizando uma plataforma como o [Render](https://render.com) (ou outros milhares de serviços que fazem a mesma coisa), que vai abstrair todo o processo de configurar o ambiente, realizar o deploy quando houver um merge, e vai te dar outras regalias, como backups de banco de dados e etc. Essa facilidade toda tem o seu custo ($), e caso você queira subir outro serviço, os custos vão subir bem mais rápido.
112112

113-
![](/images/serverswift/render.png)
113+
![](serverswift/render.png)
114114

115115
Não tem muito o que ficar falando sobre essas plataformas, cada uma vai ter suas particularidades, mas é uma alternativa que eu gosto muito de usar! Quanto menos tempo a gente gasta na infraestrutura, mais a gente pode investir no produto em si, e isso é o que importa no final. Até a próxima!

site/Content/br/swiftui-motion-effects.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Pequenos detalhes fazem toda a diferença, e pequenos detalhes me deixam desprop
1212

1313
Uma das interações mais legais e super tranquilas da gente implementar nos nossos apps UIKit é o UIInterpolationMotionEffect, que dá aquele efeito de parallax quando mexemos o celular, mais conhecido pelo efeito [Perspectiva](https://support.apple.com/pt-br/HT200285) que podemos aplicar nas imagens de fundo de nossos iPhones e iPads. Mas quando tentei adicionar um em minha View de SwiftUI, fui pego por isso daqui:
1414

15-
![Imagem com uma view de SwiftUI onde um motionEffect que tenta ser aplicado nela dá erro, porque não existe](/images/motion/motionError.png)
15+
![Imagem com uma view de SwiftUI onde um motionEffect que tenta ser aplicado nela dá erro, porque não existe](motion/motionError.png)
1616

1717
Eis que descubro, pesquisando pela documentação que não existe uma forma de colocar um efeito desses nativamente com o SwiftUI! Meu primeiro pensamento foi criar uma UIViewRepresentable que tivesse a minha View dentro de um container do SwiftUI, fazendo um bridge de SwiftUI -> UIKit -> SwiftUI, que tentei fazer, mas sem muito sucesso.
1818

@@ -237,6 +237,6 @@ extension View {
237237

238238
E com isso, o nosso código lá do começo funciona perfeitamente, da forma que eu queria que ele funcionasse :)
239239

240-
![Imagem com uma view de SwiftUI onde um motionEffect é aplicado com sucesso](/images/motion/motionSucc.png)
240+
![Imagem com uma view de SwiftUI onde um motionEffect é aplicado com sucesso](motion/motionSucc.png)
241241

242242
O projeto completo com o exemplo do card e o reader do giroscópio está no [meu GitHub](https://github.com/loloop/SwiftInMotion), e deixo meus agradecimentos aqui ao [@Alan Pégoli](https://twitter.com/alanpegoli) que fez o beta test e apontou uma falha gritante no artigo :)

site/Content/br/unity3d-and-apple.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Este artigo foi escrito há muito tempo atrás. O site onde hospedei os gifs na
1717

1818
Este artigo é uma cópia do meu artigo publicado para o equinociOS 2016, uma reunião de artigos criados durante o equinócio feitos pela comunidade Apple no Brasil.
1919

20-
![O fps mais inovador que eu já joguei em anos](/images/unity/muchocaliente.png)
20+
![O fps mais inovador que eu já joguei em anos](unity/muchocaliente.png)
2121

2222
Nascida no OS X em 2005 e portada para o resto do mundo todo, a Unity é uma das maiores game engines da atualidade, e uma das melhores escolhas que se pode fazer quando o assunto é gamedev para aparelhos mobile. Com suporte a tantas plataformas que eu não duvidaria que ela funciona até em torradeiras, e isto naturalmente traz aquela dúvida que todo framework que promete mil e uma plataformas traz: Mas realmente funciona?
2323

@@ -28,7 +28,7 @@ Agora que você já conhece um pouco da Unity e o core dela, vamos começar? :)
2828

2929
## Primeiros Passos
3030

31-
![Página Inicial da Unity3D](/images/unity/GetUnity.png)
31+
![Página Inicial da Unity3D](unity/GetUnity.png)
3232

3333
Bom, vamos começar baixando a Unity né? Não precisa se preocupar muito se ela vai rodar bem no seu Mac, pois estou usando um [MacBook Air de 2010](https://support.apple.com/kb/sp618?locale=en_US) para escrever este artigo. A versão que eu usei pra escrever ele é a 5.3.2, mas já saiu uma versão mais nova, a 5.3.3, mas tudo que eu fizer aqui deve funcionar nela sem o menor dos problemas. O download tá no [site da Unity](http://unity3d.com/download), e a Personal Edition é completa o suficiente pra funcionar com tudo que a gente vai usar.
3434

@@ -38,7 +38,7 @@ Não se esqueça de marcar pro Download Assistant baixar o Build Support para as
3838

3939
### O Unity Remote
4040

41-
![Unity Remote 4 na App Store](/images/unity/UnityRemote4.png)
41+
![Unity Remote 4 na App Store](unity/UnityRemote4.png)
4242
<p><span class="caption muted"><a href="https://itunes.apple.com/us/app/unity-remote-4/id871767552?mt=8">Download do UnityRemote na App Store</a></span></p>
4343

4444
Testar builds em aparelhos iOS com a Unity é um processo demorado e chato. Para aqueles testes onde queremos apenas o input do celular, o Remote é uma
@@ -52,7 +52,7 @@ Para deixar o mais amigável para se trabalhar com o Git, nós precisamos mudar
5252

5353
Fica bem mais fácil de identificar problemas assim, já que antes não era possível fazer diff dos arquivos, mas isso deixa os commits um número de linhas bem exagerado, como dá pra ver nos graphs do GitHub de um dos meus projetos.
5454

55-
![3mi linhas de código](/images/unity/3MilhoesDeLinhas.png)
55+
![3mi linhas de código](unity/3MilhoesDeLinhas.png)
5656

5757
### Player Settings
5858

site/Sources/InkMarkdownRenderer.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,37 @@ extension MarkdownParser {
6060
return decorated
6161
}
6262
parser.addModifier(codeBlockModifier)
63+
let imageModifier = Modifier(target: .images) { html, markdown in
64+
do {
65+
let altRegex = try Regex(#"alt="([^"]+)""#)
66+
let altValue = try altRegex.firstMatch(in: html)?.last?.value
67+
let altValueString = String(altValue as? Substring ?? "")
68+
69+
let srcRegex = try Regex(#"src="([^"]+)""#)
70+
let value = try srcRegex.firstMatch(in: html)?.last?.value
71+
let valueString = String(value as? Substring ?? "")
72+
73+
/*
74+
// TODO: Fork Ink and add `metadata` as a modifier parameter
75+
// TODO: so we can get the article slug and automatically append it here
76+
let last = valueString.split(separator: "/").last ?? ""
77+
print(regex)
78+
print(last)
79+
*/
80+
81+
return if altValueString.isEmpty {
82+
#"<img src="/images/\#(valueString)" />"#
83+
} else {
84+
#"<img src="/images/\#(valueString)" alt="\#(altValueString)" />"#
85+
}
86+
87+
} catch {
88+
fatalError("InkMarkdownParser: Failed to modify image URL")
89+
}
90+
}
91+
92+
parser.addModifier(imageModifier)
93+
6394
return parser
6495
}
6596
}

0 commit comments

Comments
 (0)