Ir para o conteúdo

Tutorial 7 - Iniciando o uso de bibliotecas externas

Até o momento, o aplicativo que criamos usou apenas o nosso próprio código, além do código fornecido pelo BeeWare. Entretanto, em um aplicativo do mundo real, você provavelmente desejará usar uma biblioteca de terceiros, baixada do Python Package Index (PyPI).

Vamos modificar nosso aplicativo para incluir uma biblioteca de terceiros.

Adição de um pacote

Vamos modificar nosso aplicativo para dizer um pouco mais do que apenas "Hi, there!".

Para gerar um texto mais interessante para a caixa de diálogo, usaremos uma biblioteca chamada Faker. Faker é um pacote Python que gera conteúdo falso, incluindo nomes e blocos de texto. Os nomes e as palavras no bloco de texto são gerados a partir de uma lista arbitrária de palavras fornecidas pelo Faker. Vamos usar o Faker para construir uma mensagem falsa, como se alguém estivesse respondendo ao usuário.

Vamos adicionar uma chamada de API httpx ao nosso aplicativo. Adicione uma importação na parte superior do app.py para importar httpx:

import faker

Para tornar nosso tutorial assíncrono, modifique o manipulador de eventos say_hello() para que ele tenha a seguinte aparência:

async def say_hello(self, widget):
    fake = faker.Faker()
    await self.main_window.dialog(
        toga.InfoDialog(
            greeting(self.name_input.value),
            f"A message from {fake.name()}: {fake.text()}",
        )
    )

Vamos executar nosso aplicativo atualizado no modo de desenvolvedor do Briefcase para verificar se nossa alteração funcionou.

(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in <module>
    from briefcase.__main__ import main
File ".../venv/lib/python3.13/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.13/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.13/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.13/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.13/site-packages/briefcase/commands/base.py", line 14, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'
(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in <module>
    from briefcase.__main__ import main
File ".../venv/lib/python3.13/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.13/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.13/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.13/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.13/site-packages/briefcase/commands/base.py", line 14, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'
(beeware-venv) C:\...>briefcase dev
Traceback (most recent call last):
File "...\venv\bin\briefcase", line 5, in <module>
    from briefcase.__main__ import main
File "...\venv\lib\python3.13\site-packages\briefcase\__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File "...\venv\lib\python3.13\site-packages\briefcase\cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File "...\venv\lib\python3.13\site-packages\briefcase\commands\__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File "...\venv\lib\python3.13\site-packages\briefcase\commands\build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File "...\venv\lib\python3.13\site-packages\briefcase\commands\base.py", line 14, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'

Não é possível executar um aplicativo Android no modo de desenvolvedor - use as instruções para a plataforma de desktop escolhida.

Não é possível executar um aplicativo iOS no modo de desenvolvedor - use as instruções para a plataforma de desktop escolhida.

O que aconteceu? Adicionamos faker ao nosso código, mas não o adicionamos ao ambiente virtual usado para executar o aplicativo no modo de desenvolvimento.

Quando o Briefcase executa um aplicativo no modo de desenvolvimento, ele cria um ambiente virtual independente para esse aplicativo, independente do ambiente em que você executa briefcase. Se o seu aplicativo não declarar que precisa de uma biblioteca específica, essa biblioteca não será instalada no ambiente virtual de desenvolvimento.

Então, como você adiciona um novo requisito ao seu aplicativo?

Atualização de dependências

No diretório raiz do seu aplicativo, há um arquivo chamado pyproject.toml. Esse arquivo contém todos os detalhes de configuração do aplicativo que você forneceu quando executou originalmente o briefcase new.

o pyproject.toml é dividido em seções; uma das seções descreve as configurações do seu aplicativo:

[tool.briefcase.app.helloworld]
formal_name = "Hello World"
description = "A Tutorial app"
long_description = """More details about the app should go here.
"""
sources = ["src/helloworld"]
requires = []

A opção requires descreve as dependências da nossa aplicação. É uma lista de strings que especifica as bibliotecas (e, opcionalmente, as versões das bibliotecas) que você deseja incluir na sua aplicação.

Modifique a configuração requires para que fique assim:

requires = [
    "faker",
]

Ao adicionar essa configuração, estamos dizendo ao Briefcase "quando você compilar meu aplicativo, execute pip install httpx no pacote de aplicativos". Qualquer coisa que seja uma entrada legal para pip install pode ser usada aqui - portanto, você poderia especificar:

  • Uma versão específica da biblioteca (por exemplo, "httpx==0.19.0");
  • Um intervalo de versões de biblioteca (por exemplo, "httpx>=0.19");
  • Um caminho para um repositório git (por exemplo, "git+https://github.com/encode/httpx"); ou
  • Um caminho de arquivo local (no entanto, esteja avisado: se você fornecer seu código a outra pessoa, esse caminho provavelmente não existirá no computador dela!)

Mais abaixo no pyproject.toml, você notará outras seções que dependem do sistema operacional, como [tool.briefcase.app.helloworld.macOS] e [tool.briefcase.app.helloworld.windows]. Essas seções também têm uma configuração requires. Essas configurações permitem definir dependências adicionais específicas da plataforma. Assim, por exemplo, se você precisar de uma biblioteca específica da plataforma para lidar com algum aspecto do seu aplicativo, poderá especificar essa biblioteca na seção requires específica da plataforma, e essa configuração será usada somente para essa plataforma. Você notará que as bibliotecas toga são todas especificadas na seção requires específica da plataforma - isso ocorre porque as bibliotecas necessárias para exibir uma interface de usuário são específicas da plataforma.

No nosso caso, queremos que o httpx seja instalado em todas as plataformas, portanto, usamos a configuração requires em nível de aplicativo. As dependências no nível do aplicativo sempre serão instaladas; as dependências específicas da plataforma são instaladas além das dependências no nível do aplicativo.

Depois de adicionar o novo requisito, salve pyproject.toml e execute briefcase dev -r. O sinalizador -r informa ao Briefcase que os requisitos foram alterados e que o ambiente virtual de desenvolvimento precisa ser atualizado:

(beeware-venv) $ briefcase dev -r

[helloworld] Activating dev environment...
...
Recreating virtual environment (dev.cpython-313-darwin)... done

[hello-world] Installing requirements...
...

[helloworld] Starting in dev mode...
===========================================================================

Ao inserir um nome e pressionar o botão, você verá uma caixa de diálogo semelhante:

Caixa de diálogo do Tutorial 7 do Hello World, no
macOS

(beeware-venv) $ briefcase dev -r

[helloworld] Activating dev environment...
...
Recreating virtual environment (dev.cpython-313-x86_64-linux-gnu)... done

[hello-world] Installing requirements...
...

[helloworld] Starting in dev mode...
===========================================================================

Ao inserir um nome e pressionar o botão, você verá uma caixa de diálogo semelhante:

Caixa de diálogo do Tutorial 7 do Hello World, no
Linux

(beeware-venv) C:\...>briefcase dev -r

[helloworld] Activating dev environment...
...
Recreating virtual environment (dev.cp313-win_amd64)... done

[hello-world] Installing requirements...
...

[helloworld] Starting in dev mode...
===========================================================================

Ao inserir um nome e pressionar o botão, você verá uma caixa de diálogo semelhante:

Caixa de diálogo Hello World Tutorial 7, no
Windows

Não é possível executar um aplicativo Android no modo de desenvolvedor - use as instruções para a plataforma de desktop escolhida.

Não é possível executar um aplicativo iOS no modo de desenvolvedor - use as instruções para a plataforma de desktop escolhida.

Possíveis erros ao executar briefcase dev

Se você ainda estiver recebendo um erro ao executar briefcase dev, certifique-se de que:

  1. Você adicionou faker à lista requires em pyproject.toml;
  2. Você salvou suas alterações em pyproject.toml; e
  3. Você incluiu o argumento -r ao executar briefcase dev -r.

Na primeira vez que você executa seu aplicativo usando briefcase dev, o argumento -r é adicionado automaticamente para você — é por isso que não precisamos usar o argumento -r até agora. O argumento -r só é necessário quando você adiciona, remove ou altera um requisito depois de executar seu aplicativo no modo de desenvolvimento. Se você apenas atualizou o código, pode executar briefcase dev como temos feito no restante deste tutorial.

Executando o aplicativo atualizado

Agora temos um aplicativo funcional, usando uma biblioteca de terceiros, rodando em modo de desenvolvimento. Vamos empacotar esse código de aplicativo atualizado como um aplicativo independente. Como fizemos alterações no código, precisamos seguir as mesmas etapas do Tutorial 4:

Atualize o código no aplicativo empacotado:

(beeware-venv) $ briefcase update

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstrua o aplicativo:

(beeware-venv) $ briefcase build

[helloworld] Adhoc signing app...
[helloworld] Built build/helloworld/macos/app/Hello World.app

E, por fim, execute o aplicativo:

(beeware-venv) $ briefcase run

[helloworld] Starting app...
===========================================================================

No entanto, quando o aplicativo for executado, você verá um erro no console, além de uma caixa de diálogo de falha:

Falha do aplicativo Hello World Tutorial 7, no
macOS

Atualize o código no aplicativo empacotado:

(beeware-venv) $ briefcase update

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstrua o aplicativo:

(beeware-venv) $ briefcase build

[helloworld] Finalizing application configuration...
...

[helloworld] Building application...
...

[helloworld] Built build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/bin/helloworld

E, por fim, execute o aplicativo:

(beeware-venv) $ briefcase run

[helloworld] Starting app...
===========================================================================

No entanto, quando o aplicativo for executado, você verá um erro no console:

Traceback (most recent call last):
  File "/usr/lib/python3.13/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.13/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/helloworld-0.0.1/usr/app/hello_world/__main__.py", line 1, in <module>
    from helloworld.app import main
  File "/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/helloworld-0.0.1/usr/app/hello_world/app.py", line 8, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'

Unable to start app helloworld.

Atualize o código no aplicativo empacotado:

(beeware-venv) C:\...>briefcase update

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstrua o aplicativo:

(beeware-venv) C:\...>briefcase build
...

[helloworld] Built build\helloworld\windows\app\src\Toga Test.exe

E, por fim, execute o aplicativo:

(beeware-venv) C:\...>briefcase run

[helloworld] Starting app...
===========================================================================

No entanto, quando o aplicativo for executado, você verá um erro no console, além de uma caixa de diálogo de falha:

Falha no aplicativo Hello World Tutorial 7, no
Windows

Atualize o código no aplicativo empacotado:

(beeware-venv) $ briefcase update android

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstrua o aplicativo:

(beeware-venv) $ briefcase build android

[helloworld] Updating app metadata...
...
[helloworld] Built build/helloworld/android/gradle/app/build/outputs/apk/debug/app-debug.apk

E, por fim, execute o aplicativo (selecionando um simulador quando solicitado):

(beeware-venv) $ briefcase run android

[helloworld] Following device log output (type CTRL-C to stop log)...
===========================================================================

No entanto, quando o aplicativo for executado, você verá um erro no console:

--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.example.helloworld, PID: 8289
E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helloworld/org.beeware.android.MainActivity}: com.chaquo.python.PyException: ModuleNotFoundError: No module named 'faker'
E/AndroidRuntime:   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635)
E/AndroidRuntime:   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
E/AndroidRuntime:   at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
E/AndroidRuntime:   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
E/AndroidRuntime:   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
E/AndroidRuntime:   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
E/AndroidRuntime:   at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime:   at android.os.Looper.loopOnce(Looper.java:201)
E/AndroidRuntime:   at android.os.Looper.loop(Looper.java:288)
E/AndroidRuntime:   at android.app.ActivityThread.main(ActivityThread.java:7839)
E/AndroidRuntime:   at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
E/AndroidRuntime: Caused by: com.chaquo.python.PyException: ModuleNotFoundError: No module named 'faker'
E/AndroidRuntime:   at <python>.helloworld.app.<module>(app.py:8)
E/AndroidRuntime:   at <python>.java.chaquopy.import_override(import.pxi:60)
E/AndroidRuntime:   at <python>.__main__.<module>(__main__.py:1)
E/AndroidRuntime:   at <python>.runpy._run_code(<frozen runpy>:88)
E/AndroidRuntime:   at <python>.runpy._run_module_code(<frozen runpy>:98)
E/AndroidRuntime:   at <python>.runpy.run_module(<frozen runpy>:226)
E/AndroidRuntime:   at <python>.chaquopy_java.call(chaquopy_java.pyx:352)
E/AndroidRuntime:   at <python>.chaquopy_java.Java_com_chaquo_python_PyObject_callAttrThrowsNative(chaquopy_java.pyx:324)
E/AndroidRuntime:   at com.chaquo.python.PyObject.callAttrThrowsNative(Native Method)
E/AndroidRuntime:   at com.chaquo.python.PyObject.callAttrThrows(PyObject.java:232)
E/AndroidRuntime:   at com.chaquo.python.PyObject.callAttr(PyObject.java:221)
E/AndroidRuntime:   at org.beeware.android.MainActivity.onCreate(MainActivity.java:85)
E/AndroidRuntime:   at android.app.Activity.performCreate(Activity.java:8051)
E/AndroidRuntime:   at android.app.Activity.performCreate(Activity.java:8031)
E/AndroidRuntime:   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
E/AndroidRuntime:   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)
E/AndroidRuntime:   ... 12 more
I/Process : Sending signal. PID: 8289 SIG: 9

Atualize o código no aplicativo empacotado:

(beeware-venv) $ briefcase update iOS

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstrua o aplicativo:

(beeware-venv) $ briefcase build iOS

[helloworld] Updating app metadata...
...
[helloworld] Built build/helloworld/ios/xcode/build/Debug-iphonesimulator/Hello World.app

E, por fim, execute o aplicativo (selecionando um simulador quando solicitado):

(beeware-venv) $ briefcase run iOS

...
[helloworld] Following simulator log output (type CTRL-C to stop log)...
===========================================================================

No entanto, quando o aplicativo for executado, você verá um erro no console:

Application has crashed!
========================
Traceback (most recent call last):
  File "/Users/rkm/Library/Developer/CoreSimulator/Devices/FD7EA28A-6D72-4064-9D8A-53CC8308BB6F/data/Containers/Bundle/Application/D9DD590B-DA32-4EE1-8F78-78658379CAB7/Hello World.app/app/helloworld/__main__.py", line 1, in <module>
    from helloworld.app import main
  File "/Users/rkm/Library/Developer/CoreSimulator/Devices/FD7EA28A-6D72-4064-9D8A-53CC8308BB6F/data/Containers/Bundle/Application/D9DD590B-DA32-4EE1-8F78-78658379CAB7/Hello World.app/app/helloworld/app.py", line 8, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'

Mais uma vez, o aplicativo não foi iniciado porque o faker não foi instalado - mas por quê? Já não instalamos o faker?

Temos, mas apenas no ambiente de desenvolvimento. Cada aplicativo criado também tem seu próprio ambiente independente, que é uma das coisas que o Briefcase produz quando você executa briefcase build. Quando executamos briefcase dev -r, adicionamos faker ao nosso ambiente de desenvolvimento, mas não ao aplicativo empacotado. Também precisamos executar briefcase update -r para que o Briefcase saiba que os requisitos do aplicativo empacotado foram alterados:

(beeware-venv) $ briefcase update -r

[helloworld] Updating application code...
Installing src/hello_world...

[helloworld] Updating requirements...
Collecting faker
  Using cached faker-37.3.0-py3-none-any.whl.metadata (15 kB)
...
Installing collected packages: tzdata, travertino, std-nslog, rubicon-objc, fonttools, toga-core, faker, toga-cocoa
Successfully installed faker-37.3.0 fonttools-4.58.1 rubicon-objc-0.5.1 std-nslog-1.0.3 toga-cocoa-0.5.1 toga-core-0.5.1 travertino-0.5.1 tzdata-2025.2

[helloworld] Removing unneeded app content...
...

[helloworld] Application updated.
(beeware-venv) $ briefcase update -r

[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.13

[helloworld] Updating application code...
Installing src/hello_world...

[helloworld] Updating requirements...
Collecting faker
  Using cached faker-37.3.0-py3-none-any.whl.metadata (15 kB)
...
Installing collected packages: tzdata, travertino, std-nslog, rubicon-objc, fonttools, toga-core, faker, toga-cocoa
Successfully installed faker-37.3.0 fonttools-4.58.1 rubicon-objc-0.5.1 std-nslog-1.0.3 toga-cocoa-0.5.1 toga-core-0.5.1 travertino-0.5.1 tzdata-2025.2

[helloworld] Removing unneeded app content...
...

[helloworld] Application updated.
(beeware-venv) C:\...>briefcase update -r

[helloworld] Updating application code...
Installing src/helloworld...

[helloworld] Updating requirements...
Collecting faker
  Using cached faker-37.3.0-py3-none-any.whl.metadata (15 kB)
...
Installing collected packages: tzdata, travertino, std-nslog, rubicon-objc, fonttools, toga-core, faker, toga-cocoa
Successfully installed faker-37.3.0 fonttools-4.58.1 rubicon-objc-0.5.1 std-nslog-1.0.3 toga-cocoa-0.5.1 toga-core-0.5.1 travertino-0.5.1 tzdata-2025.2

[helloworld] Removing unneeded app content...
...

[helloworld] Application updated.
(beeware-venv) $ briefcase update android -r

[helloworld] Updating application code...
Installing src/helloworld... done

[helloworld] Updating requirements...
Writing requirements file... done

[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done

[helloworld] Application updated.
(beeware-venv) $ briefcase update iOS -r

[helloworld] Updating application code...
Installing src/helloworld... done

[helloworld] Updating requirements...
Looking in indexes: https://pypi.org/simple, https://pypi.anaconda.org/beeware/simple
Collecting faker
  Using cached faker-37.4.0-py3-none-any.whl.metadata (15 kB)
...

Installing app requirements for iPhone simulator... done

[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done

[helloworld] Application updated.

Depois de atualizar, você pode executar briefcase build e briefcase run e verá o aplicativo empacotado com o novo comportamento de diálogo.

Observação

A opção -r para atualizar os requisitos também é aceita pelos comandos build e run, portanto, se quiser atualizar, compilar e executar em uma única etapa, você pode usar briefcase run -u -r.

Pacotes Python de terceiros para dispositivos móveis e Web

O Faker é apenas um exemplo de um pacote Python de terceiros - uma coleção de código que não faz parte do que o Python fornece de fábrica. Esses pacotes de terceiros são mais comumente distribuídos usando o Python Package Index (PyPI) e instalados em seu ambiente virtual local. Neste tutorial, usamos o pip, mas há outras opções.

Em plataformas de desktop (macOS, Windows, Linux), qualquer pip instalável pode ser adicionado aos seus requisitos. Em plataformas móveis e da Web, suas opções são ligeiramente limitadas.

Em resumo, qualquer pacote puro Python (ou seja, qualquer pacote criado a partir de um projeto escrito somente em Python) pode ser usado sem dificuldade. Alguns pacotes, entretanto, são criados a partir de projetos que contêm Python e outras linguagens (por exemplo, C, C++, Rust etc.). O código escrito nessas linguagens precisa ser compilado em módulos binários específicos da plataforma antes de poder ser usado, e esses módulos binários pré-compilados só estão disponíveis em plataformas específicas. As plataformas móveis e da Web têm requisitos muito diferentes das plataformas de desktop "padrão". No momento, a maioria dos pacotes Python não fornece binários pré-compilados para plataformas móveis e da Web.

No PyPI, os pacotes geralmente são fornecidos em um formato de distribuição pré-construído chamado wheels. Para verificar se um pacote é Python puro, dê uma olhada na página de downloads do projeto no PyPI. Se as rodas fornecidas tiverem um sufixo -py3-none-any.whl (por exemplo, Faker), então elas são rodas Python puras. No entanto, se as rodas tiverem extensões específicas de versão e plataforma (por exemplo, Pillow, que tem rodas com sufixos como -cp313-cp313-macosx_11_0_arm64.whl e -cp39-cp39-win_amd64.whl), então a roda contém um componente binário. Esse pacote não pode ser instalado em plataformas móveis ou da Web, a menos que uma roda compatível com essas plataformas tenha sido fornecida.

No momento, a maioria dos pacotes binários no PyPI não fornece rodas compatíveis com dispositivos móveis ou com a Web. Para preencher essa lacuna, o BeeWare fornece binários para alguns módulos binários populares (incluindo numpy, pandas e cryptography). Essas rodas não são distribuídas no PyPI, mas o Briefcase instalará essas rodas se elas estiverem disponíveis.

O BeeWare pode fornecer binários para alguns módulos binários populares (incluindo numpy, pandas e cryptography). Normalmente, é possível compilar pacotes para plataformas móveis, mas isso não é fácil de configurar, o que está fora do escopo de um tutorial introdutório como este.

Próximos passos

Agora temos um aplicativo que usa uma biblioteca de terceiros! No Tutorial 8, aprenderemos como garantir que nosso aplicativo permaneça responsivo à medida que adicionarmos uma lógica de aplicativo mais complexa.