Giter VIP home page Giter VIP logo

popup-bridge-ios's Introduction

PopupBridge iOS

GitHub Actions Tests

PopupBridge is an iOS library that allows WKWebViews to open popup windows in an ASWebAuthenticationSession browser and send data back to the parent page in the WKWebView.

PopupBridge is also available for Android.

See the Frequently Asked Questions to learn more about PopupBridge. See Using PayPal in a WebView to use PopupBridge with PayPal.

Requirements

  • iOS 14.0+
  • Xcode 15.0+
  • Swift 5.9+, or Objective-C

Installation

CocoaPods

To integrate using CocoaPods, add the following line to your Podfile:

pod 'PopupBridge'

Carthage

To integrate using Carthage, add github "braintree/popup-bridge-ios" to your Cartfile, and add the frameworks to your project.

Swift Package Manager

To integrate using Swift Package Manager, select File > Swift Packages > Add Package Dependency and enter https://github.com/braintree/popup-bridge-ios as the repository URL. Tick the checkbox for PopupBridge.

If you look at your app target, you will see that PopupBridge is automatically linked as a framework to your app (see General > Frameworks, Libraries, and Embedded Content).

Sample App

To run the sample app, clone the repo, open PopupBridge.xcworkspace and run the Demo app target.

Quick Start

  1. Integrate PopupBridge with your WKWebView:

    class ViewController: UIViewController {
        
        var webView: WKWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: 300, height: 700))
        var popupBridge: POPPopupBridge?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(webView)
            
            popupBridge = POPPopupBridge(webView: webView)
            
            // Replace http://localhost:3099/ with the webpage you want to open in the webview
            let url = URL(string: "http://localhost:3099/")!
            webView.load(URLRequest(url: url))
        }
    }
  2. Use PopupBridge from the web page by writing some JavaScript:

    var url = 'http://localhost:3099/popup'; // or whatever the page is that you want to open in a popup
    
    if (window.popupBridge) {
      // Open the popup in a browser, and give it the deep link back to the app
      popupBridge.open(url + '?popupBridgeReturnUrlPrefix=' + popupBridge.getReturnUrlPrefix());
    
      // Optional: define a callback to process results of interaction with the popup
      popupBridge.onComplete = function (err, payload) {
        if (err) {
          console.error('PopupBridge onComplete Error:', err);
        } else if (!err && !payload) {
          console.log('User closed popup.');
        } else {
          alert('Your favorite color is ' + payload.queryItems.color);
        }
      };
    } else {
      var popup = window.open(url);
    
      window.addEventListener('message', function (event) {
        var color = JSON.parse(event.data).color;
    
        if (color) {
          popup.close();
          alert('Your favorite color is ' + color);
        }
      });
    }
  3. Redirect back to the app inside of the popup:

    <h1>What is your favorite color?</h1>
    
    <a href="#red" data-color="red">Red</a>
    <a href="#green" data-color="green">Green</a>
    <a href="#blue" data-color="blue">Blue</a>
    
    <script src="jquery.js"></script>
    <script>
    $('a').on('click', function (event) {
      var color = $(this).data('color');
    
      if (location.search.indexOf('popupBridgeReturnUrlPrefix') !== -1) {
        var prefix = location.search.split('popupBridgeReturnUrlPrefix=')[1];
        // Open the deep link back to the app, and send some data
        location.href = prefix + '?color=' + color;
      } else {
        window.opener.postMessage(JSON.stringify({ color: color }), '*');
      }
    });
    </script>

Frequently Asked Questions

Why use PopupBridge?

WKWebView can open popups through its WKUIDelegate, which can be implemented to present the popup in a new WKWebView.

However, WKWebViews do not display an address bar or an HTTPS lock icon. If the popup receives sensitive user information (e.g. login credentials), users must implicitly trust that the web page is not redirecting them to a malicious spoofed page that may steal their information. PopupBridge solves this by using an ASWebAuthenticationSession.

What are some use cases for using PopupBridge?

  • Apps with WebViews that need to open a popup
  • When a popup window needs to to send data from the popup back to the WKWebView
  • When the popup window needs to display the HTTPS lock icon to increase user trust
  • Apps that use OAuth

How does it work?

  • PopupBridge attaches to a WKWebView by injecting a user script to the page
    • This exposes a JavaScript interface (via window.popupBridge) for the web page to interact with the iOS code
  • The web page detects whether the page has access to window.popupBridge; if so, it creates a ASWebAuthenticationSession to open the popup URL
    • The web page can also use popupBridge.onComplete as a callback
  • If the user taps the Cancel button on the ASWebAuthenticationSession, popupBridge.onComplete gets called with the error and payload as null

Who built PopupBridge?

We are engineers who work on the Developer Experience team at Braintree.

Why did Braintree build PopupBridge?

Short answer: to accept PayPal as a payment option when mobile apps are using a WebView to power the checkout process.

PayPal authentication occurs in a popup window. However, this causes issues with Braintree merchants who use a web page to power payments within their apps: they can't accept PayPal because WebViews cannot open popups and return the PayPal payment authorization data to the parent checkout page.

PopupBridge solves this problem by allowing braintree-web or PayPal's Checkout.js to open the PayPal popup from a secure mini-browser.

Using PayPal in a WebView

WebView-based checkout flows can accept PayPal with PopupBridge and the Braintree JS SDK or PayPal's Checkout.js. For the authentication flow, PayPal requires a popup window—which can be simulated with PopupBridge.

Setup

  1. Create a web-based checkout that accepts PayPal using Checkout.js or the Braintree JS SDK
  2. Create a native mobile app that opens the checkout in a WKWebView (See the quick start instructions)
  3. Integrate the PopupBridge library
  4. Collect device data
    • To help detect fraudulent activity, collect device data before performing PayPal transactions. This is similar to collecting device data with our native iOS SDK with a few differences:
      1. Rather than importing the entire data collector, you can add just PayPalDataCollector to your app: pod 'Braintree/PayPalDataCollector'
      2. Implement methods in your native app depending on whether you are doing one-time payments or vaulted payments. See the iOS code snippets for PayPal + PopupBridge
  5. Profit!

Versions

This SDK abides by our Client SDK Deprecation Policy. For more information on the potential statuses of an SDK check our developer docs.

Major version number Status Released Deprecated Unsupported
2.x.x Active October 2023 TBA TBA
1.x.x Inactive 2016 October 2024 October 2025

Author

Braintree, [email protected]

License

PopupBridge is available under the MIT license. See the LICENSE file for more info.

popup-bridge-ios's People

Contributors

agedd avatar billwerges avatar braintreeps avatar crookedneighbor avatar dpa99c avatar epreuve avatar intelliot avatar jaxdesmarais avatar lkorth avatar quinnjn avatar rzulkoski avatar saschpe avatar scannillo avatar sestevens avatar skunkworks avatar stechiu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

popup-bridge-ios's Issues

Documentation error

In the demo code you have a lowercase r that stops it from working. :(

...
  if (location.search.indexOf('popupBridgeReturnUrlPrefix') !== -1) {
    var prefix = location.search.split('popupBridgereturnUrlPrefix=')[1];   // <------- here
    // Open the deep link back to the app, and send some data
    location.href = prefix + '?color=' + color;
  } else {
    window.opener.postMessage(JSON.stringify({ color: color }), '*');
  }
...

[__NSFrozenDictionaryM _fastCStringContents:]: unrecognized selector sent to instance

General information

  • SDK/Library version: 1.2.0
  • iOS Version and Device: iOS 15.5 iPhone 13 Pro Max (Simulator)
  • Integration type and version: SPM / Xcode 13.3.1

Issue description

We tried to integrate the library into the Swift project.
There build error linked to library source code.

P.S.: We decided that was caused by the combination of the Objective-C lib + Swift project.

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSFrozenDictionaryM _fastCStringContents:]: unrecognized selector sent to instance 0x600000e3acc0'

image

image

http://localhost:3099/

General information

Have completed 1-3 steps.

Please explain what this URL actually is? I am getting blank page on my app.
(http://localhost:3099/) What should be this URL on my App?

Also if we run the popupbridgeexample target. The simulator shows blank and nothing really happens. Could you please let me know the issue.

Thanks,
Laxman

  • SDK/Library version:
  • iOS Version and Device:
  • Integration type and version:

Issue description

Remove Excluded architectures flag ( Apple M1 )

General information

  • iOS Version and Device: Any IOS Emulator on M1 Processor
  • Integration type and version: CocoaPods

Issue description

Following line in PopupBridge.release and PopupBridge.debug files (Pods/PopupBridge/SupportFiles) cause a compilation Error on my M1.
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
I am then forced to use Rosetta which causes runtime Problems with my Capacitor App.

After removing the line above from the following files i was able to compile and run the app.

Pods/PupupBridge/SuppoprtFiles/PupupBridge.debug
Pods/PupupBridge/SuppoprtFiles/PupupBridge.release
Targets Support Files/Pods-App/Pods-App.debug
Targets Support Files/Pods-App/Pods-App.release

The EXCLUDED_ARCHS Flag in the Podspec of this project causes also my Pods-App to contain that flag, which has an impact on my whole project.

iOS17/Xcode15 Compatability Check

Hi,

We are using this SDK v1.2.0 and we are targeting for iOS17 release soon, So we wanted to confirm if this SDK is compatible with iOS17/Xcode15?

Extra header POPPopUpBridge.h interfering with Carthage

General information

  • SDK/Library version: 1.0.0
  • iOS Version and Device: iOS 12.4 Simulator and Xcode 10.3 (10G8)
  • Integration type and version: Carthage 0.33.0

Issue description

It looks like POPPopUpBridge.h wasn't renamed/removed properly and there is still an extra file hanging out at PopupBridge/Classes/POPPopUpBridge.h as well as some confusion in the project file itself. It would appear that properly removing the old (PopUp) header and re-adding the new (Popup) header to the project fixes an issue with bringing in the framework through Carthage.

Project showing the original issue: https://github.com/rzulkoski/PopupBridgeCarthageError

Unable to destroy webview

General information

  • iOS Version and Device: iOS 11 and above
  • Integration type and version: CocoaPods latest version (pod 'PopupBridge')

Issue description

We have an issue where the deinit method in our view controller is not being called because the Popup bridge holds a strong reference our webview as per the below line in the POPPopupBridge.m class:

@Property (nonnull, nonatomic, strong) WKWebView *webView;

As it is a nonnull and strong we are unable to set the instance to nil which is causing a memory leak that we are unable to fix.

var url = 'http://localhost:3099/';

General information

Could you please explain what do you mean by step

  1. Use PopupBridge from the web page by writing some JavaScript:

  2. Redirect back to the app inside of the popup:

How to do these steps on iOS app?

Explain

  • SDK/Library version:
  • iOS Version and Device:
  • Integration type and version:

Issue description

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.