Wrapply logoTutoriais Wrapply
🧩 Bridge nativo

API Bridge Wrapply: conecte o site a funções nativas do app

Guia prático das APIs bridge nativas da Wrapply para notificações, deeplinks, links de entrada, compras in-app e localização em apps Flutter gerados.

Referência Native Bridge

O app Flutter gerado expõe window.Wrapply dentro da WebView. O seu site pode chamar esse objeto para usar recursos nativos apenas quando o módulo correspondente estiver ativado. Aguarde sempre wrapplyNativeBridgeReady e trate sempre { ok:false, error } como um caso normal de fallback.

APIQuando usarEntradaResposta
window.Wrapply.isNativeApp()Detecta o wrapper nativononetrue inside app
notifications.requestPermission(payload)Solicita permissão de notificações{ provider }{ ok, permission, granted }
notifications.getToken(payload)Lê ou atualiza o token do dispositivo{ provider, refresh? }{ ok, token, provider }
notifications.refreshToken(payload)Regenera o token. Alias: updateToken{ provider }{ ok, token, refreshed:true }
notifications.show(payload)Mostra uma notificação local imediata{ title, body?, data? }{ ok, shown:true }
notifications.getStatus(payload)Lê status do provedor e permissões{ provider }{ ok, granted, configured? }
iap.getProducts(payload)Lê produtos configurados na loja{ packageName, productIds }{ ok, available, products }
iap.purchase(payload)Inicia uma compra in-app{ packageName, productId, consumable? }{ ok, purchaseStarted }
iap.restorePurchases(payload)Restaura compras não consumíveis{ packageName }{ ok, latestPurchases }
deepLinks.open(payload)Abre URL interna, externa, telefone, email ou WhatsApp{ type, url/value }{ ok, type, url }
wrapply://open/pathAbre o app instalado por email, SMS ou site externoexternal linkloads https://DOMAIN/path
Quando recursos bridge são ativados, o Wrapply também fornece um PDF com módulos ativos, chamadas exatas, configuração do provedor e notas para revisão nas lojas.

Provedores de notificações

O site pode escolher o provedor de notificações em cada chamada. O Wrapply inclui somente o provedor selecionado no app gerado.

ProvedorUsoConfiguração necessáriaNota importante
localPadrão seguro, token local salvo em shared preferencesNenhum arquivo externoÚtil para testes/sessão; não é token push remoto real
firebaseProvedor Firebase Cloud Messagingandroid/app/google-services.json e opcional ios/Runner/GoogleService-Info.plistSe os arquivos faltarem, retorna ok:false/configured:false
onesignalProvedor OneSignalOneSignal App ID na configuração/buildExige setup OneSignal antes de enviar push remotas

Permissões do dispositivo

Câmera, microfone e geolocalização usam APIs web padrão. O wrapper adiciona permissões nativas Android/iOS quando o recurso está ativo.

FunçãoAPI webPermissões nativasComportamento
Câmeranavigator.mediaDevices.getUserMedia({ video:true })Android CAMERA, iOS NSCameraUsageDescriptionUsa API web padrão; o app mostra prompt nativo
Microfonenavigator.mediaDevices.getUserMedia({ audio:true })Android RECORD_AUDIO, iOS NSMicrophoneUsageDescriptionUsa API web padrão; não exige chamada direta ao Wrapply
Geolocalizaçãonavigator.geolocation.getCurrentPosition(...)Android COARSE/FINE, texto iOS location usageLocalização precisa é opcional e deve ser ativada só quando necessário

Exemplos por tipo de código

Estes exemplos são pequenos de propósito: mostram o padrão correto de integração, enquanto o PDF gerado lista os módulos ativos daquele app.

Ready helper

function onWrapplyReady(callback) {
if (window.Wrapply && window.Wrapply.__nativeBridgeReady) {
callback(window.Wrapply);
return;
}
window.addEventListener("wrapplyNativeBridgeReady", () => {
callback(window.Wrapply);
}, { once: true });
}

JavaScript

document.querySelector("#notify").addEventListener("click", async () => {
if (!window.Wrapply?.notifications) return alert("Available inside the app");
const permission = await window.Wrapply.notifications.requestPermission({ provider: "firebase" });
if (!permission.ok || !permission.granted) return;
const token = await window.Wrapply.notifications.getToken({ provider: "firebase" });
await fetch("/api/device-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: token.token, platform: "wrapply" })
});
});

TypeScript

type WrapplyResponse = Promise<Record<string, unknown>>;
declare global {
interface Window {
Wrapply?: {
__nativeBridgeReady?: boolean;
isNativeApp: () => Promise<boolean>;
notifications?: {
requestPermission: (p: Record<string, unknown>) => WrapplyResponse;
getToken: (p: Record<string, unknown>) => WrapplyResponse;
refreshToken: (p: Record<string, unknown>) => WrapplyResponse;
updateToken: (p: Record<string, unknown>) => WrapplyResponse;
show: (p: Record<string, unknown>) => WrapplyResponse;
getStatus: (p: Record<string, unknown>) => WrapplyResponse;
};
iap?: { purchase: (p: Record<string, unknown>) => WrapplyResponse };
deepLinks?: { open: (p: Record<string, unknown>) => WrapplyResponse };
};
}
}
export {};

React

import { useEffect, useState } from "react";
export function useWrapplyBridge() {
const [ready, setReady] = useState(false);
useEffect(() => {
if (window.Wrapply?.__nativeBridgeReady) return setReady(true);
const onReady = () => setReady(true);
window.addEventListener("wrapplyNativeBridgeReady", onReady);
return () => window.removeEventListener("wrapplyNativeBridgeReady", onReady);
}, []);
return { ready, Wrapply: ready ? window.Wrapply : null };
}

Vue 3

import { ref, onMounted, onBeforeUnmount } from "vue";
export function useWrapplyBridge() {
const ready = ref(false);
const markReady = () => { ready.value = true; };
onMounted(() => {
if (window.Wrapply?.__nativeBridgeReady) markReady();
else window.addEventListener("wrapplyNativeBridgeReady", markReady);
});
onBeforeUnmount(() => window.removeEventListener("wrapplyNativeBridgeReady", markReady));
return { ready };
}

Angular

@Injectable({ providedIn: "root" })
export class WrapplyBridgeService {
async requestToken(provider = "firebase") {
if (!window.Wrapply?.notifications) {
return { ok: false, error: "Bridge unavailable" };
}
return window.Wrapply.notifications.getToken({ provider });
}
}

jQuery

$("#wrapply-token").on("click", async function () {
if (!window.Wrapply?.notifications) return;
const result = await window.Wrapply.notifications.getToken({ provider: "local" });
$("#wrapply-output").text(JSON.stringify(result, null, 2));
});

PHP / Laravel Blade

<button onclick="buyNativeProduct()">Buy premium</button>
<script>
async function buyNativeProduct() {
if (!window.Wrapply?.iap) return;
const result = await window.Wrapply.iap.purchase({
packageName: "{{ config('app.mobile_package') }}",
productId: "premium_monthly",
consumable: false
});
console.log(result);
}
</script>

WordPress

add_action('wp_footer', function () { ?>
<script>
window.wrapplyNotify = async function () {
if (!window.Wrapply?.notifications) return;
return window.Wrapply.notifications.show({
title: "WordPress",
body: "Notification called from theme/plugin"
});
};
</script>
<?php });

Deep links

// External links from email, SMS, CRM or website
wrapply://open/profile
wrapply://open/checkout?plan=premium
wrapply://open/orders/123

// Native action inside the app
await window.Wrapply.deepLinks.open({ type: "internal_url", url: "https://example.com/account" });
await window.Wrapply.deepLinks.open({ type: "mailto", value: "support@example.com" });
await window.Wrapply.deepLinks.open({ type: "tel", value: "+390000000000" });
await window.Wrapply.deepLinks.open({ type: "whatsapp", value: "+390000000000" });

O que o bridge Wrapply faz

O bridge expõe uma API JavaScript dentro da WebView. Seu site pode chamar window.Wrapply e o app Flutter executa a ação nativa somente se a função foi ativada.

Ao selecionar funções bridge, a Wrapply também fornece um PDF com chamadas exatas, módulos ativos e notas de configuração.

Ative somente os módulos necessários

Notifications
Local/Firebase/OneSignal provider, permission request, token read/refresh and local notification display.
Actions and deeplinks
Open internal WebView URLs, external browser URLs, phone, email and WhatsApp from your website.
Inbound links
Open the installed app from a configured scheme or app link, then route the user to the right page.
In-app purchases
Query store products, start purchase, restore purchases and send results to your backend for validation.
Location
Add the native permission base for maps, nearby results or geolocation flows.

Setup flow

1. Configure features

Enable only the modules you need in the Wrapply configurator.

2. Add required files

Upload Firebase files or provider identifiers when the selected provider requires them.

3. Generate source code

Wrapply writes conditional dependencies, AndroidManifest entries, Info.plist keys and bridge modules.

4. Add JavaScript calls

Call window.Wrapply from your website only after checking the bridge exists.

5. Test before publishing

Test native permissions, tokens, purchases and links on real Android/iOS devices.

Exemplos JavaScript reais

Use these calls from your website only after verifying that window.Wrapply exists.

Notifications

async function enablePush() {
if (!window.Wrapply?.notifications) return;
await window.Wrapply.notifications.requestPermission({ provider: 'firebase' });
const token = await window.Wrapply.notifications.getToken({ provider: 'firebase' });
await fetch('/api/device-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token.token, platform: 'app' })
});
}
window.Wrapply?.notifications?.show({ title: 'Order updated', body: 'Your request is ready' });

Actions and deeplinks

window.Wrapply?.deepLinks?.open({ type: 'internal_url', url: 'https://example.com/account' });
window.Wrapply?.deepLinks?.open({ type: 'mailto', value: 'support@example.com' });
window.Wrapply?.deepLinks?.open({ type: 'tel', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'whatsapp', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'url', url: 'https://example.com/help' });

In-app purchases

async function buyPremium() {
if (!window.Wrapply?.iap) return;
await window.Wrapply.iap.getProducts({ productIds: ['premium_monthly'] });
const result = await window.Wrapply.iap.purchase({
productId: 'premium_monthly',
consumable: false,
applicationUserName: currentUser.id
});
await fetch('/api/iap/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result)
});
}

Location

if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
console.log(position.coords.latitude, position.coords.longitude);
});
}

O que você recebe

Conditional source code
Only selected dependencies, permissions and bridge files are included.
Configuration files
Firebase files, OneSignal App ID and iOS optional files are inserted only when requested.
PDF implementation guide
Ao selecionar funções bridge, a Wrapply também fornece um PDF com chamadas exatas, módulos ativos e notas de configuração.
Store review support
Payment, notification and permission modules should be tested before publishing.

FAQ bridge

Does the bridge work on the public website?

No. It works inside the generated app WebView. Always check window.Wrapply before calling native APIs.

Do I need a backend?

For Firebase push and in-app purchase validation, yes. The app exposes tokens and purchase events, but the backend should send messages and validate receipts.

Can Wrapply implement it?

Yes. Managed publishing can include configuration, testing and documentation for the enabled bridge modules.

Ready to connect native features?

Guia prático das APIs bridge nativas da Wrapply para notificações, deeplinks, links de entrada, compras in-app e localização em apps Flutter gerados.