{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/product/embedded-flows/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["example-box"]},"type":"markdown"},"seo":{"title":"Embed on iOS","siteUrl":"https://docs.wise.com","projectTitle":"Wise Platform","description":"Embed a Wise Platform Embedded Flow in an iOS app."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"embed-on-ios","__idx":0},"children":["Embed on iOS"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this guide after your backend has created an Embedded Flow URL with the create recipient embedded link request endpoint."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["On iOS, load the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["url"]}," in a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WKWebView"]},". If you want to react to flow events in native code, inject a small bridge that forwards window messages from the flow to your app."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"load-the-flow","__idx":1},"children":["Load the flow"]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"WKWebView setup","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import WebKit\n\nlet webView = WKWebView(frame: .zero)\nlet flowUrl = URL(string: \"<EMBEDDED_FLOW_URL>\")!\nwebView.load(URLRequest(url: flowUrl))\n","lang":"swift"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Some flows may need camera or microphone permissions for verification steps. Make sure your app includes the required iOS permission descriptions when using flows that need device capabilities."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"optional-flow-messages","__idx":2},"children":["Optional flow messages"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Embedded Flows can emit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ready"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["resize"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["done"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]}," messages. In a native WebView, forward those messages to Swift with a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WKScriptMessageHandler"]},". If the user cancels the flow, Wise emits an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]}," message with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code"]}," set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cancelled"]},"."]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Bridge flow messages","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import WebKit\n\nfinal class FlowMessageHandler: NSObject, WKScriptMessageHandler {\n  func userContentController(\n    _ userContentController: WKUserContentController,\n    didReceive message: WKScriptMessage\n  ) {\n    guard let event = message.body as? [String: Any],\n          let type = event[\"type\"] as? String else {\n      return\n    }\n\n    switch type {\n    case \"ready\":\n      // Hide loading UI.\n      break\n    case \"resize\":\n      // Read event[\"height\"] if you need to resize the web view.\n      break\n    case \"done\":\n      // Continue your app flow.\n      break\n    case \"error\":\n      if event[\"code\"] as? String == \"cancelled\" {\n        // The user closed or cancelled the flow.\n        break\n      }\n\n      // Show a fallback state.\n      break\n    default:\n      break\n    }\n  }\n}\n\nlet contentController = WKUserContentController()\ncontentController.add(FlowMessageHandler(), name: \"wiseFlow\")\n\nlet bridgeScript = \"\"\"\nwindow.addEventListener('message', function(event) {\n  window.webkit.messageHandlers.wiseFlow.postMessage(event.data);\n});\n\"\"\"\n\ncontentController.addUserScript(\n  WKUserScript(\n    source: bridgeScript,\n    injectionTime: .atDocumentStart,\n    forMainFrameOnly: false\n  )\n)\n\nlet configuration = WKWebViewConfiguration()\nconfiguration.userContentController = contentController\n\nlet webView = WKWebView(frame: .zero, configuration: configuration)\nwebView.load(URLRequest(url: URL(string: \"<EMBEDDED_FLOW_URL>\")!))\n","lang":"swift"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"redirect-instead-of-embedding","__idx":3},"children":["Redirect instead of embedding"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a WebView is not the right fit for your app, open the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["url"]}," with the browser component you normally use for external flows. When the flow finishes, Wise returns the user to the redirect URL you provided when creating the embedded link request."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wise appends ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status=success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status=cancelled"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status=error"]}," when returning the user to your redirect URL."]}]},"headings":[{"value":"Embed on iOS","id":"embed-on-ios","depth":1},{"value":"Load the flow","id":"load-the-flow","depth":2},{"value":"Optional flow messages","id":"optional-flow-messages","depth":2},{"value":"Redirect instead of embedding","id":"redirect-instead-of-embedding","depth":2}],"frontmatter":{"seo":{"description":"Embed a Wise Platform Embedded Flow in an iOS app.","title":"Embed on iOS"},"markdown":{"lastUpdatedBlock":{"hide":true}}},"lastModified":"2026-09-04T07:44:14.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/product/embedded-flows/ios","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}