Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebView] Error trying to display PDF in web view component #1846

Closed
fjmorant opened this issue Jul 2, 2015 · 31 comments
Closed

[WebView] Error trying to display PDF in web view component #1846

fjmorant opened this issue Jul 2, 2015 · 31 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@fjmorant
Copy link

fjmorant commented Jul 2, 2015

Hello,

I am trying to display a pdf file from the app bundle but I could not do it, this is what I have done:

            <WebView
                startInLoadingState={true}
                style={styles.web}
                url={"localFile.pdf"}
                />

localFile.pdf is obviously included in the bundle but when I try to display this webview it doesn't show it properly.

From xcode I have got these error messages:

[85869:8794860] DiskImageCache: Could not resolve the absolute path of the old directory.
[85869] : CGAffineTransformInvert: singular matrix.
[85869] : CGAffineTransformInvert: singular matrix.
[85869] : CGAffineTransformInvert: singular matrix.

And I can't see it

@fjmorant
Copy link
Author

fjmorant commented Jul 2, 2015

TEMPORARY SOLUTION:

I have modified the class RCTWebView and method initWithEventDispatcher to have something like this:

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
  RCTAssertParam(eventDispatcher);

  if ((self = [super initWithFrame:CGRectZero])) {
    super.backgroundColor = [UIColor clearColor];
    _automaticallyAdjustContentInsets = YES;
    _contentInset = UIEdgeInsetsZero;
    _eventDispatcher = eventDispatcher;
    _webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen]bounds]];
    _webView.delegate = self;
    [self addSubview:_webView];
  }
  return self;
}

the key to solve the problem it has been the line:

_webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen]bounds]];

previously it was something like this:

_webView = [[UIWebView alloc] initWithFrame:self.bounds];

I guess there is some issue getting the bounds of the webview, that's why I have specified the main screen bounds.

@adnanakbar
Copy link

@JavierM84 you are a champion! Been struggling with this for days and today thought to put this as an issue and you already have a work around and it works! :)

@michaelfranz
Copy link

Great job!

@fjmorant
Copy link
Author

fjmorant commented Jul 3, 2015

thx for the compliment, I was struggling with this issue too and I thought that maybe this could help to more people temporarily

@nicklockwood
Copy link
Contributor

Hmm, the issue I have with this is that the webview may not be the full size of the screen, so using [[UIScreen mainScreen] bounds] seems questionable.

If I understand correctly, the problem is that self.bounds is {0,0,0,0} when the view is first created, and the webview doesn't like trying to display a PDF when it's size is zero. I guess the solution is either to defer setting the content until the webview has been sized correctly, or to init the webview with some temporary nonzero size, and then set it correctly later.

@fjmorant
Copy link
Author

fjmorant commented Jul 3, 2015

yes totally agree this is not a correct solution, we should provide the correct size of the webview.

I guess it works because somehow the value is adjusted properly later, but definitively it needs a value at the beginning

@brentvatne
Copy link
Collaborator

I agree with @nicklockwood's assessment - if you are using flex attributes, add an onLayout callback and set the state to point to the pdf in there.

@brentvatne brentvatne changed the title Error trying to display PDF in web view component [WebView] Error trying to display PDF in web view component Jul 4, 2015
@booxood
Copy link

booxood commented Jul 31, 2015

Finally, how to solve?

I also meet the questions... 😂 #2188

@sbdd
Copy link

sbdd commented Aug 11, 2015

If this is still an issue you can just inject the html and open the file with javascript eg.

var html = '<body style="margin:0;padding:0;width:100%;height:100%;">' +
            '<div class="">Opening PDF</div>' +
            '<script type="text/javascript">window.location.href="' + this.props.url + '"</script>' +
            '</body>';
        var options = {
            automaticallyAdjustContentInsets: false,
            html: html,
            style: {
                flex: 1,
                marginTop: 55
            }
        };
        return React.createElement(WebView, options);```

@julianacipa
Copy link

@JavierM84 Thank you for your help Javier!

@julianacipa
Copy link

 <WebView
                startInLoadingState={true}
                style={styles.web}
                url={"localFile.pdf"}
                /> 

Removing the startInLoadingState={true} line fixes the issue. The pdf gets displayed

@brentvatne
Copy link
Collaborator

Thanks @julianacipa for the follow up!

@SFantasy
Copy link

SFantasy commented Dec 7, 2015

@julianacipa Thank you for help 👍

@alvaromb
Copy link
Contributor

alvaromb commented Feb 9, 2016

Does this work on Android? I can show the pdf in iOS but not in Android.

@tommywu23
Copy link

great job!

@esthersweon
Copy link

I also am not able to get this working in Android.

@bomalley
Copy link

bomalley commented Mar 9, 2016

I can't even get this to work on iOS. I must be missing something in the source attribute now the URL is deprecated.

<WebView source={require('./foobar.pdf')}/>

That fails with Unable to resolve module.

Can anyone point me in the right direction?

@bomalley
Copy link

Okay, for future generations, here's how I solved this problem:

iOS only

render: function() {
  return <WebView source={{uri: 'My.pdf'}}/>
}

The trick is that you need to include My.pdf into your project in Xcode and make sure it's added to your build target.

Just copying it into your React Native project folder wasn't enough. It had to be part of the Xcode project itself.

@nicklockwood
Copy link
Contributor

@BOMaley the require(./foobar.pdf) version should work if the pdf file is located in the same folder as your js. It's possible I forgot to add pdf to the packager whitelist though, if so let me know and I'll fix it.

@bomalley
Copy link

@nicklockwood The require syntax did not work for me. It worked if I wanted to load an html file, but replace .html with .pdf and it fails.

@ivesy85
Copy link

ivesy85 commented Mar 21, 2016

@brentvatne The only way I have been able to get this to work is using the hack method that @JavierM84 originally posted. Just wondering if you could elaborate on your solution of adding an onLayout callback. My code is like this

var React = require('react-native');

var {
    StyleSheet,
    WebView
    } = React;

var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column'
    }
});

class ContentView extends React.Component {
    render(){
        var url = this.props.url;
        return (
            <WebView
                ref={'webView'}
                style={styles.container}
                source= {{uri: url}}
                scalesPageToFit={true}
                javaScriptEnabled={true}
                domStorageEnabled={true}
                decelerationRate="normal"
                startInLoadingState={true}
                automaticallyAdjustContentInsets={true}
            />
        )
    }
}

module.exports = ContentView;

I know it will work if I remove startInLoadingState={true} however my pdf's are online and I need the loading spinner to show the user that it is loading.

@nicklockwood
Copy link
Contributor

@bomalley The fix is just to add the "pdf" file extension in all the places where I added "html" and other extensions in this PR:

81fb985#commitcomment-15932047

If you want to put up a PR for that, I'll accept it.

ghost pushed a commit that referenced this issue Apr 19, 2016
Summary:The WebView component in iOS currently does not support displaying PDFs without providing a remote URI or manually including the assets in the xcodeproj itself. This is because the packager has not whitelisted the 'pdf' extension.

I've gone ahead and whitelisted the 'pdf extension according to the recommendation by nicklockwood

GH comment: #1846 (comment)
Closes #7004

Differential Revision: D3196019

Pulled By: nicklockwood

fb-gh-sync-id: 10a86a9232095f98f277506141de0b8af5b21ab4
fbshipit-source-id: 10a86a9232095f98f277506141de0b8af5b21ab4
ptmt pushed a commit to ptmt/react-native that referenced this issue May 9, 2016
Summary:The WebView component in iOS currently does not support displaying PDFs without providing a remote URI or manually including the assets in the xcodeproj itself. This is because the packager has not whitelisted the 'pdf' extension.

I've gone ahead and whitelisted the 'pdf extension according to the recommendation by nicklockwood

GH comment: facebook#1846 (comment)
Closes facebook#7004

Differential Revision: D3196019

Pulled By: nicklockwood

fb-gh-sync-id: 10a86a9232095f98f277506141de0b8af5b21ab4
fbshipit-source-id: 10a86a9232095f98f277506141de0b8af5b21ab4
zebulgar pushed a commit to nightingale/react-native that referenced this issue Jun 18, 2016
Summary:The WebView component in iOS currently does not support displaying PDFs without providing a remote URI or manually including the assets in the xcodeproj itself. This is because the packager has not whitelisted the 'pdf' extension.

I've gone ahead and whitelisted the 'pdf extension according to the recommendation by nicklockwood

GH comment: facebook#1846 (comment)
Closes facebook#7004

Differential Revision: D3196019

Pulled By: nicklockwood

fb-gh-sync-id: 10a86a9232095f98f277506141de0b8af5b21ab4
fbshipit-source-id: 10a86a9232095f98f277506141de0b8af5b21ab4
bubblesunyum pushed a commit to iodine/react-native that referenced this issue Aug 23, 2016
Summary:The WebView component in iOS currently does not support displaying PDFs without providing a remote URI or manually including the assets in the xcodeproj itself. This is because the packager has not whitelisted the 'pdf' extension.

I've gone ahead and whitelisted the 'pdf extension according to the recommendation by nicklockwood

GH comment: facebook#1846 (comment)
Closes facebook#7004

Differential Revision: D3196019

Pulled By: nicklockwood

fb-gh-sync-id: 10a86a9232095f98f277506141de0b8af5b21ab4
fbshipit-source-id: 10a86a9232095f98f277506141de0b8af5b21ab4
@agtb
Copy link

agtb commented Jan 19, 2017

@JavierM84 thanks, your temp fix fixed the intermittent CGAffineTransformInvert: singular matrix errors I was seeing and associated rendering fail (white screen) loading PDFs in a WebView on iOS.

cpojer pushed a commit to facebook/metro that referenced this issue Jan 26, 2017
Summary:The WebView component in iOS currently does not support displaying PDFs without providing a remote URI or manually including the assets in the xcodeproj itself. This is because the packager has not whitelisted the 'pdf' extension.

I've gone ahead and whitelisted the 'pdf extension according to the recommendation by nicklockwood

GH comment: facebook/react-native#1846 (comment)
Closes facebook/react-native#7004

Differential Revision: D3196019

Pulled By: nicklockwood

fb-gh-sync-id: 10a86a9232095f98f277506141de0b8af5b21ab4
fbshipit-source-id: 10a86a9232095f98f277506141de0b8af5b21ab4
@andy9775
Copy link
Contributor

andy9775 commented Jun 8, 2017

I still seem to be getting this error in RN 0.44, although it's intermittent

@stantoncbradley
Copy link

stantoncbradley commented Jun 14, 2017

for anyone looking to fix this with layoutChanged, this worked for me:

constructor() {
    super();
    this.state = {
      layoutChanged: false,
    };
  }

  renderPDF = () => (
    <WebView
      source={{ uri: this.props.navigation.state.params.url }}
    />
  )

  render() {
    return (
      <View
        style={styles.container}
        onLayout={() => this.setState({ layoutChanged: true })}
      >
        {this.state.layoutChanged ? this.renderPDF() : <View />}
      </View>
    );
  }

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: COLORS.nearWhitePrimary,
  },

@Elijen
Copy link

Elijen commented Sep 2, 2017

@brentvatne online PDFs not loading with startInLoadingState={true} seems to be a bug in WebView. Shouldn't this issue be re-opened?

@brunoti
Copy link

brunoti commented Sep 26, 2017

@Elijen

@brentvatne online PDFs not loading with startInLoadingState={true} seems to be a bug in WebView. [...]

Same here

@brunoti
Copy link

brunoti commented Sep 26, 2017

With startInLoadingState={true} and renderLoading={() => <Spinner />} to load an online PDF it only shows a blank screen. Removing the quoted props it works normally, but shows an annoying black screen while loading the PDF

@sooyang
Copy link

sooyang commented Oct 5, 2017

I need to render a pdf online which is why startInLoadingState={true} to be helpful to indicate that the page is loading to users. But I came across the same issue that the pdf does not render after setting startInLoadingState={true}.

An example workaround for this is as follows:

class MyWeb extends Component {
  constructor() {
    super();
    this.state = {
      loaded: false,
    };
  }

  render() {
    return (
      <View style={{flex: 1}}>
        <WebView
          source={{ uri: 'facebook.com' }}
          style={{ flex: 1 }}
          onLoadEnd={() => this.setState({ loaded: true })}
        />
        {this.state.loaded ? null : <ActivityIndicator animating size="large" style={{flex: 1}} />}
      </View>
    );
  }
}

Using state, if the page is not loaded I will display my own ActivityIndicator.
WebView have a function onLoadEnd which is called when WebView load succeeds or fails. I will use the callback to set the state loaded to true thus hiding the ActivityIndicator and display the WebView instead

@brunoti
Copy link

brunoti commented Oct 5, 2017

Sometimes the PDF don't open and it just shows a white screen.

Is this a react-native problem or an iOS Webview problem? Any news?

I think this issue should be reopened.

@willdurand
Copy link
Contributor

We are experiencing the same issue as reported by @brunoti. PDFs fail to load for no obvious reason.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests