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 in window 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 in window 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 in window 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