Coder Social home page Coder Social logo

naoufal / react-native-safari-view Goto Github PK

View Code? Open in Web Editor NEW
492.0 5.0 113.0 495 KB

A React Native wrapper for Safari View Controller.

Home Page: https://www.npmjs.com/package/react-native-safari-view

JavaScript 30.67% Objective-C 58.87% Ruby 10.45%
react-native apple safari-view-controller safari

react-native-safari-view's Introduction

React Native Safari View

react-native version npm version npm downloads Code Climate

React Native Safari View is a Safari View Controller wrapper for React Native.

react-native-safari-view

Documentation

Install

npm i --save react-native-safari-view

Support

Due to the rapid changes being made in the React Native ecosystem, we are not officially going to support this module on anything but the latest version of React Native. The current supported version is indicated on the React Native badge at the top of this README. If it's out of date, we encourage you to submit a pull request!

Usage

Linking the Library

In order to use Safari View, you must first link the library your project. There's excellent documentation on how to do this in the React Native Docs.

Displaying the Safari View

Once you've linked the library, you'll want to make it available to your app by requiring it:

var SafariView = require('react-native-safari-view');

Displaying the Safari View is as simple as calling:

SafariView.show({
  url: 'https://github.com/naoufal'
});

URL Change Notifications

There isn't an API for retrieving URL changes provided by SFSafariViewController or its delegate in iOS, so there's no way to know where the user is navigating to. However, it is possible to get a notification when the Safari View navigates to an URL scheme specified by your app (e.g. your-app-name://). This is especially useful for implementing callback oriented flows such as in OAuth2 / OpenID Connect.

To get URL notifications for your URL scheme you'll need to:

  1. Register an URL scheme in your Xcode Project
  2. Make sure you've set up Linking in your react-native project.
  3. Listen for URL changes in your react-native code (i.e. Linking.addEventListener('url', eventHandler));

Example

Using Safari View in your app will usually look like this:

import React, { Component } from "react";
import SafariView from "react-native-safari-view";

class YourComponent extends Component {
  constructor(props) {
    super(props);
  }

  _pressHandler() {
    SafariView.isAvailable()
      .then(SafariView.show({
        url: "https://github.com/naoufal"
      }))
      .catch(error => {
        // Fallback WebView code for iOS 8 and earlier
      });
  }

  render() {
    return (
      <View>
        ...
        <Button onPress={this._pressHandler}>
          Show Safari View
        </Button>
      </View>
    );
  }
}

Methods

show(safariOptions)

Displays a Safari View with the provided url.

Arguments

  • safariOptions - An Object containing a url key and optionally a readerMode key, a tintColor, and/or a barTintColor.

safariOptions

  • url - A String containing the url you want to load in the Safari View
  • readerMode - A Boolean indicating to use Safari's Reader Mode if available
  • tintColor - A String containing a hex, rgba or rgba color to use for the browser controls
  • barTintColor - A String containing a hex, rgba or rgba color to use for the background of the browser controls (only available on iOS 10 and higher)
  • fromBottom - A 'Boolean' indicating to open the Safari View from the bottom

Examples

SafariView.show({
  url: "http://facebook.github.io/react/blog/2015/03/26/introducing-react-native.html",
  readerMode: true // optional,
  tintColor: "#000" // optional
  barTintColor: "#fff" // optional
});

isAvailable()

Checks if Safari View is available on the device.

Example

SafariView.isAvailable()
  .then(available => {
    console.log("SafariView is available.");
  })
  .catch(error => {
    console.log(error);
  });

dismiss()

Dismisses the currently active Safari View.

Example

SafariView.dismiss()

Events

The following events are fired by the Safari View.

onShow

Example

let showSubscription = SafariView.addEventListener(
  "onShow",
  () => {
    StatusBar.setBarStyle("light-content");
  }
);

onDismiss

Example

let dismissSubscription = SafariView.addEventListener(
  "onDismiss",
  () => {
    StatusBar.setBarStyle("default");
  }
);

License

Copyright (c) 2015, Naoufal Kadhom

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

react-native-safari-view's People

Contributors

1st8 avatar aforty avatar amwam avatar bartgryszko avatar chaithanyaprathyush avatar dozoisch avatar greis avatar headlessme avatar jamesreggio avatar jerolimov avatar kalasjocke avatar koenpunt avatar mohitpinkhand avatar myusuf3 avatar naoufal avatar plrthink avatar ptmt avatar rt2zz avatar seasonyuu avatar trabianmatt avatar weinshel 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  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  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

react-native-safari-view's Issues

Please add tintColor property

In the session, it was explained that you can customize the tint color of the toolbar items and done button. So could you please add that feature to react-native-safari-view?

I've tried to make it by myself though I know barely nothing about OC. However it seems that it's not like initWithURL and entersReaderIfAvailable so I cannot manage it. Here is what I've found.

You have to set the tintColor property of the SFSafariViewController's view.

override func viewDidLoad() {
  super.viewDidLoad()
  UIBarButtonItem.appearance().tintColor = UIColor.redColor()
}

Thanks in advance!

Detect changes of URL?

It is possible to track changes of URL while navigating?
A close up view from RN code?

Can't resolve './SafariViewManager'

i try to use this library open safari browser, when the Platform is iOS ,

but it give me this error, Module not found: Can't resolve './SafariViewManager' in '/Users/dev/apps/node_modules/react-native-safari-view'

and i use react-native-web, i did added uncompiled packages to my babel loader's includes.

anybody know why ?

Flow Annotations errors

Hi!

The file index.ios.js contains @flow but does not contain any annotation within the file. This leads to many errors. I'm willing to do a PR to either remove @flow or add some annotations. Which solution do you prefer?

First one makes it 0 maintenance in the future. Second one means you will have to maintain the flow annotations if modifications are made in the code base, but that they can also be used by people using the lib.

[Question] Why is the API promise-based?

At first I wanna say THANK YOU for a good work. I use your project for the first time and it was easy to integrate and to work with :-)

If I look at the code in detail I am not sure why the API is promise-based? I cannot find any Objective-C-Code that use Threads or some concurrent stuff. Can someone explain that a little more in detail?

Thanks :-)

URL scheme no working

i have added URL scheme , it was working on Safari browser, but not working on Sarariview, when click the link, nothing happened.

Has anyone got this working with RN 0.44?

It's not working for me. I'm running React Native 0.44.2, React 16.0.0-alpha.6, React Native Safari View 2.0.0. Just opens a separate Safari window outside of the app.

Here's my code:

onPress = () => {
  SafariView.isAvailable()
    .then(SafariView.show({ url: this.state.courseUrl }))
    .catch(() => Linking.openURL(this.state.courseUrl));
}

TypeError: Cannot read property 'show' of undefined

Hi. I installed this package with npm i --save react-native-safari-view and then use it in my component:

...

import SafariView from 'react-native-safari-view';

...

pressHandler = () => {
  SafariView.show({ url: this.props.webviewUrl })
  .then((bool) => { console.log('available', bool); })
  .then(SafariView.show({
    url: this.props.webviewUrl,
  }))
  .catch(error => {
    console.log('error:', error);
  });
};

...

render() {
  return (
    <View style={styles.root}>
      <TouchableOpacity
        style={{ borderWidth: 1, alignItems: 'center', padding: 20 }}
        onPress={this.pressHandler}>
        <Text>Press</Text>
      </TouchableOpacity>
    </View>
  );
}

And get this error:

TypeError: Cannot read property 'show' of undefined
    at SafariViewManager.ios.js:27
    at tryCallTwo (core.js:45)
    at doResolve (core.js:200)
    at new Promise (core.js:66)
    at Object.show (SafariViewManager.ios.js:26)
    at Object.Cart._this.pressHandler [as onPress] (Cart.js:77)
    at Constructor.touchableHandlePress (TouchableOpacity.js:119)
    at Constructor.proxiedMethod [as touchableHandlePress] (createPrototypeProxy.js:44)
    at Constructor._performSideEffectsForTransition (Touchable.js:715)
    at Constructor.proxiedMethod [as _performSideEffectsForTransition] (createPrototypeProxy.js:44)

I logged the NativeModules object imported from react-native and it has not SafariViewManager property (== undefined).
May be I missed something?
RN version is 0.31

I ran node node_modules/react-native/local-cli/cli.js link and did't get any effect from this.

Safari view layout

Safari view doesn't layout my html content properly. But it is properly displayed in Safari app.

[Android] Can't run generate APK

Hello,

I used the react-native-safari-view in my iOS app, now I want to make an android app. But I can't because the safari view does not support android. How can I make my app run on android?

Like it should work on iOS with this package and on android without this package??

Any Ideas or suggestions for my problem
Thanks
Alex

Undefined Issue: undefined is not an object (evaluating 'NativeSafariViewManager.show')`

"react": "~15.3.1 ",
"react-native": "^0.35.0",
"react-native-safari-view": "^1.2.0"

I am using it as its is recommended in the docs.

'import SafariView from 'react-native-safari-view';

SafariView.isAvailable()
.then(SafariView.show({
url : "myurl"
}))
.catch(error => {
// Fallback WebView code for iOS 8 and earlier
console.log("test err ",error);
});`

error : Possible Unhandled Promise Rejection (id: 1): undefined is not an object (evaluating 'NativeSafariViewManager.show')

I have tried consoling the component "SafariView"
this is what i got.

{ show: [Function: show],
dismiss: [Function: dismiss],
isAvailable: [Function: isAvailable],
addEventListener: [Function: addEventListener],
removeEventListener: [Function: removeEventListener] }

it correctly prints out all the function but, when I use it throws warning and not opening.
tried in device and simulator.

Thanks in Advance.

setting readerMode props not work

while I am setting props like this

var props = {
    url: url,
    readerMode: false,
    tintColor: '#445262',
  };

SafariView always make entersReaderIfAvailable as YES, performs like a bug.

Not working on RN 0.51.0: Module cannot be null

I've managed to use RNSV on older versions of RN, but not on 0.51.0

Looking at the stacktrace, it seems like SafariViewManager cannot be imported (probably because it hasn't been installed correctly?).

Could it be related to this issue?
skycocker/react-native-sfsafariviewcontroller#8

I'm on react 16.0.0, react-native 0.51.0 and RNSV 2.1.0.

schermafbeelding 2017-12-06 om 14 40 56

Update: just upgraded the example from this repo to 0.51.0 without any problems. Still getting the error on my own project though. Any help would be much appreciated.

Lower podspec deployment target

I get it, Safari View is a feature of iOS 9 but hear me out... I want to use Safari when it .isAvailable() and other fallback to React's Linking. I don't want to raise my Podfile deployment target (currently iOS 8.3) in order to satisfy this particular components podspec.

So is it possible to lower the deployment target and simply error out during .isAvailable() (edit: it already does this) so that we can use a fallback method?

Thanks for reading!

In landscape mode, Safari view header overlaps status bar

An iOS app can be configured to optionally maintain the status bar in landscape mode. In my app I have done so. Unfortunately now the Safari View header now overlaps the status bar when trigger in landscape mode.

See below image:
screen shot 2017-09-05 at 9 36 13 pm

I'm using react-native-safari-view 2.0.0 and react-native 0.48.0

Safari view won't show when opened from a Modal

I'm trying to open the Safari View by pressing on a button inside a , but Safari View refuses to open and it throws this warning: "Warning: Attempt to present <SFSafariViewController: 0x13fb1cc80> on <UIViewController: 0x13e8024c0> whose view is not in the window hierarchy!"

Web page doesn't load on device

latest xcode and RN 0.13.

Webpages load fine in simulator but it just goes idle when safari opens up inside the app on device.

Installation not working

I'm on react native version 17 and I get the Red Screen of Death when I try to require react-native-safari-view in my project.

image

I've triple checked that I've installed the library correctly and linked the binaries.

image

Has anything changed recently?

SafariView works ok on simulator but doesn't work on physical devices.

I've followed the instructions here and everything is ok and running on iOS simulator but when I try to run my app on the device it always fails.

openSafari = (url) => {
    SafariView.isAvailable()
    .then(SafariView.show({
        url,
        fromBottom: true,
        tintColor: "rgb(0,0,0)",
    }))
    .catch(() => {
        Actions.webViewModal({ url, onClose: this.closeLink })
    })
}

crashes when url has character "|"

crashes when url has character "|"
this is an example url:

http://www.cnbc.com/2018/01/16/why-ripple-is-not-cashing-out-its-xrp-holdings.html?__source=twitter|main

Error thrown:

Exception 'The specified URL has an unsupported scheme. Only HTTP and HTTPS URLs are supported.' was thrown while invoking show on target SafariViewManager with params (
        {
        barTintColor = 4281089616;
        tintColor = 4294967295;
        url = "http://www.cnbc.com/2018/01/16/why-ripple-is-not-cashing-out-its-xrp-holdings.html?__source=twitter|main";
    },

closing SafariView programmatically

Hello and thank you for this. I'm implementing oAuth2 and I found that I need some sort of closing once I detect the proper URL.

I have already prepared the PR for this, please take a look at this and let me know,

Thanks,
Ali

SafariView.show is undefined

When SafariView is imported as

import SafariView from 'react-native-safari-view'
SafariView.show({ url: selectedShowtime.bookingUrl });

We get that show is undefined.

I've linked the library and still get this error.

react-native-cli: 1.2.0
react-native: 0.41.2

Promise never resolves in with `show()`

When calling show, you return a promise like so:

return new Promise((resolve, reject) => {
      NativeSafariViewManager.show(options, (error) => {
        if (error) {
          return reject(error);
        }

        resolve(true);
      });
    });

this promise only resolves in the callback you pass to the native show method:

(error) => {
        if (error) {
          return reject(error);
        }

        resolve(true);
      }

But that callback is never called in the native code (see here: https://github.com/naoufal/react-native-safari-view/blob/master/SafariViewManager.m). You might want the callback to be called in the completion callback here or for the promise to resolve straight away.

Please fix this issue as soon as possible as it is very blocking for correct error handling :(

How do you test? (Invariant Violation: Native module cannot be null.)

Hi,

I'm trying to test my root component which uses react-native-safarview and I receive the following error:

Invariant Violation: Native module cannot be null.

  at invariant (node_modules/fbjs/lib/invariant.js:25:15)
  at new NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:29:7)
  at Object.<anonymous> (node_modules/react-native-safari-view/SafariViewManager.ios.js:11:20)
  at Object.<anonymous> (node_modules/react-native-safari-view/index.js:7:26)

App.test.tsx

import React from "react";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import App from "../App";

Enzyme.configure({ adapter: new Adapter() });

it("renders correctly", () => {
  const wrapper = shallow(<App />);
  expect(wrapper).toMatchSnapshot();
});

I created a folder /jest/setup.js and updated my jest.config.js as it's suggested here.

jest.mock("Linking", () => {
  return {
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    openURL: jest.fn(),
    canOpenURL: jest.fn(),
    getInitialURL: jest.fn()
  };
});

but it didn't work. How can I fix it?

jest.config.js

module.exports = {
  cacheDirectory: ".jest/cache",
  preset: "react-native",

  globals: {
    "ts-jest": {
      useBabelrc: true
    }
  },
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
  setupFiles: ["<rootDir>/jest/setup.js"],
  snapshotSerializers: ["enzyme-to-json/serializer"],
  transform: {
    "^.+\\.jsx?$": "<rootDir>/node_modules/babel-jest",
    "^.+\\.tsx?$": "ts-jest"
  },
  transformIgnorePatterns: [
    "node_modules/(?!react-native|react-router-native)/"
  ],
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  testPathIgnorePatterns: ["\\.snap$", "<rootDir>/node_modules/"]
};

"dependencies": {
    "axios": "^0.18.0",
    "react": "^16.4.1",
    "react-native": "0.55.4",
    "react-native-blur": "^3.2.2",
    "react-native-safari-view": "^2.1.0",
    "react-native-vector-icons": "^4.6.0",
    "react-redux": "^5.0.7",
    "react-router-native": "^4.3.0",
    "redux": "^4.0.0",
    "redux-thunk": "^2.3.0",
    "rn-placeholder": "^1.2.0"
  },
  "devDependencies": {
    "@types/enzyme": "^3.1.11",
    "@types/enzyme-adapter-react-16": "^1.0.2",
    "@types/jest": "^23.1.2",
    "@types/react": "^16.4.2",
    "@types/react-dom": "^16.0.6",
    "@types/react-native": "^0.55.25",
    "@types/react-native-safari-view": "^2.0.3",
    "@types/react-native-vector-icons": "^4.6.1",
    "@types/react-redux": "^6.0.3",
    "@types/react-router-native": "^4.2.3",
    "@types/react-test-renderer": "^16.0.1",
    "@types/redux": "^3.6.0",
    "@types/redux-devtools-extension": "^2.13.2",
    "@types/redux-thunk": "^2.1.0",
    "babel-jest": "23.2.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react-native": "4.0.0",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "enzyme-to-json": "^3.3.4",
    "jest": "23.2.0",
    "prettier": "^1.13.6",
    "react-addons-test-utils": "^15.6.2",
    "react-dom": "^16.4.1",
    "react-native-typescript-transformer": "^1.2.10",
    "react-test-renderer": "^16.4.1",
    "redux-devtools-extension": "^2.13.5",
    "redux-mock-store": "^1.5.3",
    "ts-jest": "^22.4.6",
    "typescript": "^2.9.2"
  }

Custom Tabs (Chrome) for Android side?

I'm looking for Android alternative to this lib in my app WonderSwipe. Looks like https://github.com/droibit/react-native-custom-tabs integrates Chrome Custom Tabs, which is the closest thing to iOS's SafariView.

While I add my own compat layer to switch between these 2 libs, have anyone done work on integrating react-native-custom-tabs into this lib? https://github.com/naoufal/react-native-safari-view/blob/master/SafariViewManager.android.js is the obvious place for this.

Animate view from different direction

I noticed that in your readme you show an animated .gif of the Safari view sliding in from the bottom, whereas when I call SafariView.show() the view slides in from the right hand side. Is there a way to configure which direction the view animates in from?

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.