Platform Integration Examples
This guide provides integration examples for embedding the P2P.org Widget across different platforms and technologies. Each platform requires specific implementation approaches while maintaining the core functionality.
Swift (iOS)
Integrate the widget into iOS applications using WKWebView with proper wallet injection.
Implementation
- Use
WKWebView
with this url:TODO: UNIQUE CLIENT URL
injected
inwindow
must be initialized with your wallet
Code Example
// A simple widget scene that displays web content in a SwiftUI view
public struct WidgetScene: View {
@Environment(\.dismiss) private var dismiss
private let url: URL
private let title: String
public init(url: URL, title: String) {
self.url = url
self.title = title
}
public var body: some View {
VStack(spacing: 0) {
WebView(url: url)
.navigationBarTitle(title, displayMode: .inline)
}
.background(Colors.background)
}
}
fileprivate struct WebView: UIViewRepresentable {
let url: URL
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
webView.allowsBackForwardNavigationGestures = true
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Here must be JS injection of your wallet
// You can check example of implementation in opensource, like here
// https://github.com/AlphaWallet/alpha-wallet-ios/blob/master/modules/AlphaWalletBrowser/AlphaWalletBrowser/WKWebViewConfiguration.swift
}
}
}
View Model
/// A simple view model for widget scenes
public struct WidgetViewModel {
private let urlString: String
private let widgetTitle: String
public init(urlString: String, title: String) {
self.urlString = urlString
self.widgetTitle = title
}
/// The URL to load in the widget
public var url: URL {
guard let url = URL(string: urlString) else {
// Fallback to a default URL if the provided string is invalid
return URL(string: "https://url_of_widget_instance/")!
}
return url
}
/// The title to display in the navigation bar
public var title: String {
return widgetTitle
}
}
Kotlin (Android)
Integrate the widget into Android applications using WebView with custom wallet injection.
Implementation
- Use
WebView
with this url:TODO: UNIQUE CLIENT URL
injected
inwindow
must be initialized with your wallet
Activity Code
import android.os.Bundle
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.activity.viewModels
class WebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView
private val viewModel: WebViewViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
webView = findViewById(R.id.webView)
setupWebView()
val url = viewModel.url
webView.loadUrl(url.toString())
}
private fun setupWebView() {
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
view?.loadUrl(request?.url.toString())
return false
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
val jsCode = // Injection of your wallet with actual wallet object
webView.evaluateJavascript(jsCode) { result ->
}
}
}
// WebView settings
webView.settings.apply {
javaScriptEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
}
}
}
View Model
import android.net.Uri
import androidx.lifecycle.ViewModel
class WebViewViewModel : ViewModel() {
private val urlString: String = "https://url_of_widget_instance/" // Your dynamic URL
private val widgetTitle: String = "Widget Title" // The widget title
val url: Uri
get() = Uri.parse(urlString)
val title: String
get() = widgetTitle
}
Layout XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
React Native
Integrate the widget into React Native applications using react-native-webview.
Implementation
- Use
WebView
with this url:TODO: UNIQUE CLIENT URL
injected
inwindow
must be initialized with your wallet
Code Example
import React, { useEffect, useRef } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
const WebViewScreen = () => {
// Ref to interact with the WebView
const webViewRef = useRef(null);
const url = "https://url_of_widget_instance/";
// UseEffect to inject JS after the page has loaded
const onLoadEnd = () => {
const jsCode = `
// Injection of your wallet with actual wallet object
`;
// Inject JavaScript after page load
if (webViewRef.current) {
webViewRef.current.injectJavaScript(jsCode);
}
};
return (
<View>
<WebView
ref={webViewRef}
source={{ uri: url }}
style={styles.webview}
javaScriptEnabled={true}
onLoadEnd={onLoadEnd} // Trigger JS injection after page load
startInLoadingState={true}
/>
</View>
);
};
const styles = StyleSheet.create({
webview: {
flex: 1,
},
});
export default WebViewScreen;
Web Integration (No Custom Wallet)
For web applications where you don't need custom wallet integration, use a simple iframe approach.
Implementation
- Use
iframe
with this url:TODO: UNIQUE CLIENT URL
- For wallet connection, RainbowKit is used internally
Code Example
<iframe
src="https://url_of_widget_instance/"
frameBorder="0"
width="100%"
height="100%"
/>
Responsive Integration
<div style="position: relative; width: 100%; height: 600px;">
<iframe
src="https://url_of_widget_instance/"
frameBorder="0"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
allowfullscreen
/>
</div>
Security Considerations
When integrating the widget across platforms, consider these security aspects:
JavaScript Injection
- Always validate and sanitize any data before injecting JavaScript
- Use secure communication channels between your app and the widget
- Implement proper error handling for wallet injection failures
Network Security
- Ensure HTTPS is used for all widget URLs
- Implement certificate pinning where possible
- Handle network failures gracefully
Wallet Security
- Never expose private keys or sensitive wallet data
- Use secure storage mechanisms for wallet credentials
- Implement proper session management
Testing Integration
Platform-Specific Testing
iOS Testing:
- Test on different iOS versions and device sizes
- Verify WKWebView security settings
- Test wallet injection scenarios
Android Testing:
- Test on various Android versions and devices
- Verify WebView security configurations
- Test JavaScript bridge functionality
React Native Testing:
- Test on both iOS and Android platforms
- Verify WebView component behavior
- Test navigation and state management
Web Testing:
- Test iframe behavior across browsers
- Verify responsive design
- Test wallet connection flows
Troubleshooting
Common Issues
Wallet Injection Failures:
// Check if wallet injection was successful
if (typeof window.ethereum === 'undefined') {
console.error('Wallet injection failed');
// Implement fallback or error handling
}
Network Connectivity:
// Handle network errors
webView.onerror = function(error) {
console.error('WebView error:', error);
// Show error message to user
};
Cross-Platform Compatibility:
- Ensure URLs are properly formatted for each platform
- Test deep linking and navigation flows
- Verify consistent behavior across platforms
Updated about 4 hours ago