Wrapply logoTutorial Wrapply
🧩 Bridge nativo

API Bridge Wrapply: collega il sito alle funzioni native dell’app

Guida pratica alle API bridge native di Wrapply per notifiche, deeplink, link in ingresso, acquisti in-app e posizione nelle app Flutter generate.

Riferimento Native Bridge

L’app Flutter generata espone window.Wrapply dentro la WebView. Il tuo sito può chiamare questo oggetto per usare funzioni native solo quando il modulo relativo è stato abilitato in configurazione. Attendi sempre wrapplyNativeBridgeReady e gestisci sempre { ok:false, error } come normale caso di fallback.

APIQuando usarlaInputRisposta
window.Wrapply.isNativeApp()Rileva se il sito è dentro l’app nativanonetrue inside app
notifications.requestPermission(payload)Chiede il permesso notifiche{ provider }{ ok, permission, granted }
notifications.getToken(payload)Legge o aggiorna il token dispositivo{ provider, refresh? }{ ok, token, provider }
notifications.refreshToken(payload)Rigenera il token. Alias: updateToken{ provider }{ ok, token, refreshed:true }
notifications.show(payload)Mostra una notifica locale immediata{ title, body?, data? }{ ok, shown:true }
notifications.getStatus(payload)Legge stato provider e permessi{ provider }{ ok, granted, configured? }
iap.getProducts(payload)Legge i prodotti configurati nello store{ packageName, productIds }{ ok, available, products }
iap.purchase(payload)Avvia un acquisto in-app{ packageName, productId, consumable? }{ ok, purchaseStarted }
iap.restorePurchases(payload)Ripristina acquisti non consumabili{ packageName }{ ok, latestPurchases }
deepLinks.open(payload)Apre URL interni, esterni, telefono, email o WhatsApp{ type, url/value }{ ok, type, url }
wrapply://open/pathApre l’app installata da email, SMS o sito esternoexternal linkloads https://DOMAIN/path
Quando abiliti funzioni bridge, Wrapply fornisce anche un PDF con moduli attivi, chiamate esatte, configurazione provider e note per la review degli store.

Provider notifiche

Il sito può scegliere il provider notifiche in ogni chiamata. Wrapply include nell’app generata solo il provider selezionato.

ProviderUsoConfigurazione richiestaNota importante
localDefault sicuro, token locale salvato in shared preferencesNessun file esternoUtile per test/sessione; non è un vero token push remoto
firebaseProvider Firebase Cloud Messagingandroid/app/google-services.json e opzionale ios/Runner/GoogleService-Info.plistSe mancano i file, il bridge torna ok:false/configured:false
onesignalProvider OneSignalOneSignal App ID in configurazione/buildRichiede setup OneSignal prima di inviare push remote

Permessi dispositivo

Fotocamera, microfono e geolocalizzazione usano le API standard del browser. Il wrapper aggiunge i permessi nativi Android/iOS quando la funzione è attiva.

FunzioneAPI webPermessi nativiComportamento
Fotocameranavigator.mediaDevices.getUserMedia({ video:true })Android CAMERA, iOS NSCameraUsageDescriptionUsa API web standard; l’app gestisce il prompt nativo
Microfononavigator.mediaDevices.getUserMedia({ audio:true })Android RECORD_AUDIO, iOS NSMicrophoneUsageDescriptionUsa API web standard; non serve una chiamata Wrapply diretta
Geolocalizzazionenavigator.geolocation.getCurrentPosition(...)Android COARSE/FINE, stringa iOS location usageLa posizione precisa è opzionale e va abilitata solo se serve

Esempi per tipo di codice

Questi esempi sono volutamente essenziali: mostrano il pattern corretto di integrazione, mentre il PDF generato elenca i moduli attivi per quella specifica 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" });

A cosa serve il bridge Wrapply

Il bridge espone una API JavaScript dentro la WebView. Il tuo sito può chiamare window.Wrapply e l’app Flutter generata esegue l’azione nativa solo se quella funzionalità è stata abilitata in configurazione.

Quando selezioni funzionalità bridge, Wrapply fornisce anche una guida PDF con chiamate esatte, moduli abilitati e note di configurazione del progetto generato.

Attiva solo i moduli necessari

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.

Esempi JavaScript reali

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);
});
}

Cosa ricevi con le funzioni bridge

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
Quando selezioni funzionalità bridge, Wrapply fornisce anche una guida PDF con chiamate esatte, moduli abilitati e note di configurazione del progetto generato.
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?

Guida pratica alle API bridge native di Wrapply per notifiche, deeplink, link in ingresso, acquisti in-app e posizione nelle app Flutter generate.