LogoLogo
SupportGithubSign InGet Access
  • Introduction
  • GETTING STARTED
    • SDK Quick Start
    • API Quick Start
  • Guides
    • Web
      • Create a wallet
      • Send tokens
      • Sign a transaction
      • Simulate a transaction
      • Back up a wallet
      • Recover a wallet
      • Cross-device sessions
      • Manage wallet lifecycle states
      • Web authentication methods
      • Perform swaps
      • Add custom signature hooks
      • MPC progress callbacks
      • Portal API methods
      • Configure a custom subdomain
      • Eject a wallet
      • Using the EIP-1193 Provider
      • Legacy documentation
        • Back up a wallet
          • Backup Options
        • Recover a wallet
    • iOS
      • Create a wallet
      • Send tokens
      • Sign a transaction
      • Simulate a transaction
      • Back up a wallet
      • Recover a wallet
      • Cross-device sessions
      • Manage wallet lifecycle states
      • Connect with WalletConnect
      • Build a WebView
      • Perform swaps
      • Add custom signature hooks
      • MPC progress callbacks
      • Portal API methods
      • Manage ERC20 tokens
      • Eject a wallet
      • Legacy documentation
        • Back up a wallet
          • Backup Options
          • Passkey + Enclave Storage
        • Recover a wallet
      • Troubleshooting Tips
      • Feature Flags
    • Android
      • Create a wallet
      • Send tokens
      • Sign a transaction
      • Simulate a transaction
      • Back up a wallet
      • Recover a wallet
      • Cross-device sessions
      • Manage wallet lifecycle states
      • Connect with WalletConnect
      • Build a WebView
      • Perform swaps
      • Add custom signature hooks
      • MPC progress callbacks
      • Portal API methods
      • Eject a wallet
      • Legacy documentation
        • Back up a wallet
          • Backup Options
        • Recover a wallet
    • React Native
      • Create a wallet
      • Send tokens
      • Sign a transaction
      • Simulate a transaction
      • Back up a wallet
      • Recover a wallet
      • Cross-device sessions
      • Manage wallet lifecycle states
      • Connect with WalletConnect
      • Build a WebView
      • Perform swaps
      • Add custom signature hooks
      • MPC progress callbacks
      • Portal API methods
      • Eject a wallet
      • Legacy documentation
        • Back up a wallet
          • Backup Options
        • Recover a wallet
    • Enclave MPC API
      • Create a client
      • Create a wallet
      • Send tokens
      • Sign Ethereum transactions
      • Sign Solana transactions
      • Sign Tron transactions
      • Sign Stellar Transaction
      • Concurrent Transactions
      • Back up a wallet
      • Eject a wallet
  • Reference
    • iOS
      • createWallet
      • backupWallet
      • recoverWallet
      • ejectPrivateKeys
      • registerBackupMethod
      • setGDriveConfiguration
      • setPasskeyConfiguration
      • setPasskeyAuthenticationAnchor
      • setPassword
      • availableRecoveryMethods
      • doesWalletExist
      • isWalletBackedUp
      • isWalletOnDevice
      • isWalletRecoverable
      • getBalances
      • getAssets
      • getNftAssets
      • getTransactions
      • sendSol
      • evaluateTransaction
      • buildEip155Transaction
      • buildSolanaTransaction
      • getWalletCapabilities
    • Android
      • Reference Documentation
    • React Native
      • @portal-hq/core
      • Storage adapters
        • Cloud storage
          • @portal-hq/gdrive-storage
          • @portal-hq/icloud-storage
        • Mobile storage
          • @portal-hq/keychain
          • @portal-hq/mobile-key-values
    • Enclave MPC API
      • V1 endpoints
    • Client API
      • V3 endpoints
      • V1 endpoints
    • Custodian API
      • V3 endpoints
      • V1 endpoints
    • Swaps API
      • V3 endpoints
      • V1 endpoints
  • Resources
    • Flutter
      • iOS
      • Android
    • Error codes
      • Overview
      • MPC errors
      • Network errors
      • General errors
      • Encryption errors
      • Portal Connect errors
    • Portal's MPC architecture
    • Authentication and API Keys
    • Self-Managed Backups
    • Alert Webhooks
    • Wallet lifecycle
    • Backup options
      • Password/PIN
      • GDrive
      • iCloud
      • Passkey + Enclave
    • WalletConnect metadata
    • Advanced security scanning
    • Account abstraction
    • Security firewall
    • Eject
    • Security
    • Blockchain support
    • Chain ID formatting
    • Testnet faucets
    • Going to Production
    • Rate Limits
    • Multi-backup migration guide
    • Multi-wallet migration guides
      • Migrating from Android SDK v3.x.x to v4.x.x
      • Migrating from iOS SDK v3.0.x to v3.2.x
  • Support
    • Changelog
      • Android
      • iOS
      • React Native
      • Web
      • Past Releases
        • 2024 Releases
        • 2023 Releases
    • Celo Hackathon Hub
    • Glossary
Powered by GitBook
On this page

Was this helpful?

  1. Guides
  2. iOS

Build a WebView

PreviousConnect with WalletConnectNextPerform swaps

Last updated 5 months ago

Was this helpful?

and , you can now build a web view to interact with dApps using the Portal wallet.

In the example below, we created WebViewController that initializes Portal's PortalWebView and adds it as a child view controller. PortalWebView init parameters:

  • portal: Your Portal instance.

  • url: The URL the web view should start at.

  • persistSessionData: Will persist browser session data (local-storage, cookies, etc...) when enabled.

  • onError: An error handler in case the web view throws errors.

  • onPageStart: A handler that fires when the web view is starting to load a page.

  • onPageComplete: A handler that fires when the web view has finished loading a page.

  • eip6963Icon: A string representing the Base64-encoded icon for EIP-6963 compliance.

  • eip6963Name: A string representing the name for EIP-6963 compliance.

  • eip6963Rdns: A reverse DNS string for identifying the application in EIP-6963-compliant contexts.

  • eip6963Uuid: A unique identifier string for EIP-6963 compliance.

import PortalSwift
import WebKit

class WebViewController: UIViewController, PortalWebViewDelegate {
  var portal: Portal?
  var url: String?
  var webViewController: PortalWebView?
  let persistSessionData = false
  let eip6963Icon = "Base64-encoded image string"
  let eip6963Name = "Portal MPC Wallet"
  let eip6963Rdns = "io.portalhq"
  let eip6963Uuid = "d73d7104-7e24-442b-913b-1147cd8e0325"

  override func viewDidLoad() {
    super.viewDidLoad()

    guard let portal else {
      print("❌ WebViewController error: The portal object is nil.")
      return
    }

    guard let url else {
      print("❌ WebViewController error: The url object is nil.")
      return
    }

    guard let url = URL(string: url) else {
      print("❌ WebViewController error: URL could not be derived.")
      return
    }

    webViewController = PortalWebView(
      portal: portal,                                // Your Portal instance.
      url: url,                                      // The URL the web view should start at.
      persistSessionData: persistSessionData,        // Will persist browser session data (local-storage, cookies, etc...) when enabled.
      onError: self.onErrorHandler,                  // An error handler in case the web view throws errors.
      onPageStart: self.onPageStartHandler,          // A handler that fires when the web view is starting to load a page.
      onPageComplete: self.onPageCompleteHandler,    // A handler that fires when the web view has finished loading a page.
      eip6963Icon: eip6963Icon,                      // A string representing the Base64-encoded icon for EIP-6963 compliance.
      eip6963Name: eip6963Name,                      // A string representing the name for EIP-6963 compliance.
      eip6963Rdns: eip6963Rdns,                      // A reverse DNS string for identifying the application in EIP-6963-compliant contexts.
      eip6963Uuid: eip6963Uuid                       // A unique identifier string for EIP-6963 compliance.
    )

    guard let webViewController = webViewController else {
      print("❌ WebViewController error: the PortalWebView object is nil.")
      return
    }

    webViewController.delegate = self

    // Install the WebViewController as a child view controller.
    addChild(webViewController)

    guard let webViewControllerView = webViewController.view else {
      print("❌ WebViewController error: webViewController.view could not be derived.")
      return
    }

    view.addSubview(webViewControllerView)
    webViewController.didMove(toParent: self)
  }

  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    self.webViewController = nil
  }

  func onPageStartHandler() {
    print("🔄 PortalWebView: Page loading started")
    // Add Loader here if needed
  }

  func onPageCompleteHandler() {
    print("✅ PortalWebView: Page loading completed")
    // Remove the loader here if needed
  }

  func onErrorHandler(result: Result<Any>) {
    if let error = result.error {
      print("❌ PortalWebviewError:", error, "Description:", error.localizedDescription)
      return
    }

    guard let dataAsAnyObject = result.data as? AnyObject,
          let nestedResult = dataAsAnyObject.result as? Result<Any>
    else {
      print("❌ Unable to cast result data")
      return
    }

    if let nestedError = nestedResult.error {
      print("❌ Error in nested PortalWebviewError:", nestedError)
      return
    }
  }

  func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    print("✅ Delegate method fired!", webView, navigationAction, decisionHandler)
    decisionHandler(.allow)
  }
}

And thats it! Remember that you will need a portal instance to start the web view and you will also need to initialize Portal with autoApprove: true if you want the web view to auto-approve transactions.

Next, let's explore how to use Portal's Swaps integration to perform swaps directly from your iOS app.

Once you have a Portal instance
you have generated a wallet