2016-08-17 12 views
7

हाय मैं निम्नलिखित स्थिति आ रही है लोड करने से पहले यूआरएल क्लिक किया:प्रतिक्रिया देशी Android Webview संभाल

मैं एक वेबसाइट दिखा रहा हूँ प्रतिक्रिया देशी में एक WebView गर्त। इस वेबसाइट पर पासवालेट (.pkpass) फ़ाइल का एक लिंक है (केवल उपयोग केस नहीं)। जब मैं इस वेबसाइट पर किसी भी लिंक पर क्लिक करता हूं, तो मैं यह जांचना चाहता हूं कि यह एक अन्य वेबसाइट या एक .pkpass फ़ाइल या जो भी हो। हालांकि यह चेक चल रहा है, मैं कुछ भी लोड नहीं करना चाहता हूं, बस मेरा काम पूरा होने तक प्रतीक्षा करें और मुझे पता है कि मुझे वेबसाइट खोलनी चाहिए या कोई ऐप खोलना चाहिए या जो भी हो। मैं इसे जावास्क्रिप्ट पक्ष पर बनाना चाहता हूं क्योंकि मेरे पूरे रूटिंग फ़ंक्शन वहां हैं और मेरी राय में प्रतिक्रिया-देशी इस मामले के लिए बनाए गए थे :-)

आईओएस पर यह सुंदर फ़ंक्शन onShouldStartLoadWithRequest है जो वास्तव में मुझे चाहिए।

_onShouldStartLoadWithRequest(e) { 

    if(checkUrl(e.url)) { 

     let Router = this.props.navigator.props.router; 
     let route = Router.getRouteFromUrl(e.url); 
     this.props.navigator.push(route); 

     return false; 

    } 

    return true; 
} 

मुझे ईवेंट (ई) मिल रहा है और यह जांच सकता है कि वह लोड करने का प्रयास कर रहा है। मैं e.navigation टाइप के साथ भी जांच कर सकता हूं अगर यह एक क्लिक या जो कुछ भी था।

अब एंड्रॉइड पर यह फ़ंक्शन मौजूद नहीं है। मूल तरफ shouldOverrideUrlLoading फ़ंक्शन है लेकिन यह फ़ंक्शन प्रतिक्रिया-मूल में लागू नहीं किया गया है। मुझे निम्नलिखित गिटहब मुद्दा/पीआर https://github.com/facebook/react-native/pull/6478 मिला है, मुझे लगता है, क्योंकि यह समस्या बंद है और इसलिए स्पष्टीकरण हैं, इसलिए यह कार्य लागू नहीं किया गया है।

तो मैंने खुद से एक रास्ता खोजना शुरू कर दिया। मैंने एक मूल यूआई घटक बनाया जो वेबव्यू प्रदर्शित करता है और फिर इस विधि को लागू करता है।

CustomWebViewManager.java:

package ch.mypackage; 

import android.support.annotation.Nullable; 
import android.webkit.WebView; 

import com.facebook.react.uimanager.SimpleViewManager; 
import com.facebook.react.uimanager.ThemedReactContext; 
import com.facebook.react.uimanager.annotations.ReactProp; 

public class CustomWebViewManager extends SimpleViewManager<CplusWebView> { 

    @Override 
    public String getName() { 
     return "CplusWebView"; 
    } 

    @Override 
    protected CustomWebView createViewInstance(ThemedReactContext reactContext) { 
     return new CustomWebView(reactContext); 
    } 

    @ReactProp(name = "url") 
    public void setUrl(CustomWebView view, @Nullable String url) { 
     view.loadUrl(url); 
    } 

    @ReactProp(name = "javascriptEnabled") 
    public void setJavascriptEnabled(CustomWebView view, boolean enabled) { 
     view.getSettings().setJavaScriptEnabled(enabled); 
    } 

} 

CustomWebView.java

package ch.couponplus; 

import android.util.Log; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

import com.facebook.react.bridge.Arguments; 
import com.facebook.react.bridge.ReactContext; 
import com.facebook.react.bridge.WritableMap; 
import com.facebook.react.uimanager.ThemedReactContext; 
import com.facebook.react.uimanager.events.EventDispatcher; 
import com.facebook.react.uimanager.events.RCTEventEmitter; 

public class CustomWebView extends WebView { 

    EventDispatcher eventDispatcher; 
    EventWebClient eventWebClient; 

    public CustomWebView(ThemedReactContext reactContext) { 
     super(reactContext); 
     eventWebClient = new EventWebClient(); 
     setWebViewClient(eventWebClient); 
    } 

    protected class EventWebClient extends WebViewClient { 

     @Override 
     public boolean shouldOverrideUrlLoading(WebView view, String url) { 

      WritableMap event = Arguments.createMap(); 
      event.putString("message", "MyMessage"); 
      ReactContext reactContext = (ReactContext)getContext(); 
      reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
        getId(), 
        "topChange", 
        event); 

      return true; 
     } 

    } 

} 

यह काम करता है के रूप में उम्मीद। अब मैं जेएस में shouldOverrideUrlLoading फ़ंक्शन ट्रिगर कर सकता हूं और लॉग या जो कुछ भी कर सकता हूं।

लेकिन मेरा सवाल यह है कि अब मैं फ़ंक्शन को नियंत्रित करने के लिए जावास्क्रिप्ट में true या false कैसे सेट कर सकता हूं? और क्या मेरे अपने कार्यों को उपलब्ध कराने की संभावना है? अब तक मैं केवल onChange ईवेंट ट्रिगर करने में कामयाब रहा?

मैं बस आईओएस में किए गए जैसा ही बनाना चाहता हूं :-(। शायद कोई आता है और मुझे बताता है कि किसी भी कारण से यह संभव नहीं है, लेकिन मुझे इस तरह के मामलों को कैसे संभालना चाहिए?

उत्तर

7

पता है कि यूआरएल स्कीमा हैं, लेकिन इतना मैं जानता हूँ कि वे इस मामले में काम नहीं करते।

मैं इस पर किसी भी मदद के लिए आभारी हूँ .... मैं एक वेबसाइट गर्त दिखा रहा हूँ प्रतिक्रिया-मूल में एक वेब व्यू। इस वेबसाइट पर पासवालेट (.pkpass) फ़ाइल का एक लिंक है (केवल उपयोग केस नहीं)। जब मैं इस वेबसाइट पर किसी भी लिंक पर क्लिक करता हूं तो मैंको देखना चाहता हूंचाहे वह एक अन्य वेबसाइट या एक .pkpass फ़ाइल या जो कुछ भी हो।

मुझे भी इसी तरह की समस्या थी, जहां मैं अपने प्रतिक्रिया-मूल ऐप के वेब व्यू के भीतर क्लिक किए गए लिंक के प्रकार की जांच करना चाहता था। जैसा कि आपने कहा था, आईओएस पक्ष पर फ़ंक्शन onShouldStartLoadWithRequest, जो Android पक्ष पर मौजूद नहीं है।

यह एंड्रॉइड पक्ष पर मेरा समाधान था।

<WebView 
     source={{uri: this.props.url}} 
     onLoad={this.onLoad.bind(this)} 
     onShouldStartLoadWithRequest={this._onShouldStartLoadWithRequest} 
     onNavigationStateChange = {this._onShouldStartLoadWithRequest} 
    /> 

तो फिर तुम कुछ इस तरह कर सकते हैं:

_onShouldStartLoadWithRequest(e) { 

if(checkUrl(e.url)) { 

    let Router = this.props.navigator.props.router; 
    let route = Router.getRouteFromUrl(e.url); 
    this.props.navigator.push(route); 

    this.refs[WEBVIEW_REF].stopLoading(); // <---- Add a similar line 
    //This will tell your webView to stop processing the clicked link 

    return false; 

} 

return true; 

अगर मैं आपकी समस्या को सही ढंग से समझ में आया, आप URL की जाँच के लिए एक रास्ता अपने WebView में क्लिक किया और फिर URL के आधार पर तय आगे बढ़ना चाहते हैं या रोको और कुछ और करो। जिस तरह से मैंने इसे अपने ऐप में संभाला था उससे ऊपर का समाधान।

बाहर की जाँच करें नीचे दिए गए लिंक:

https://facebook.github.io/react-native/docs/webview.html#stoploading https://github.com/facebook/react-native/pull/6886

+0

अपने जवाब के लिए धन्यवाद। यह वास्तव में एक अच्छा समाधान है जिसका उपयोग मैं अन्य मामलों में इसका उपयोग कर रहा हूं उदाहरण के लिए जब कोई लिंक होता है और मैं इसे अपने स्वयं के दृश्य में खोलना चाहता हूं, न कि वेबब्रोसर में। लेकिन अगर आप एक लिंक खोलना चाहते हैं जो .pkpass फ़ाइल जैसे किसी वेबपृष्ठ पर लक्षित नहीं है, तो ऐप क्रैश हो जाता है क्योंकि इससे पहले कि आप इसे रोक सकें, लिंक को लोड करना शुरू हो रहा है। आईओएस फ़ंक्शन के साथ आप किसी भी कार्रवाई के पहले अनुरोध को रोक सकते हैं। जहां तक ​​मैं इस मामले का परीक्षण कर सकता हूं 'ऑनविगेशनस्टेट चेंज' को पहले लोड अनुरोध के बाद बुलाया जाता है। या जब आप किसी अमान्य लिंक पर क्लिक करते हैं तो लोडिंग को रोकने का कोई तरीका मिल गया? – vanBrunneren

+0

इसे हल करने का एकमात्र तरीका यह है कि 'स्टॉपलोडिंग' फ़ंक्शन का उपयोग करके वेबव्यू लोड करना बंद करना है। लेकिन फिर आप कहते हैं कि 'ऑनविगेशनस्टेट चेंज' लोड अनुरोध के बाद बुलाया जा रहा है .. इसलिए जब तक 'स्टॉपलोडिंग()' कहा जाता है - यह बहुत देर हो सकती है और ऐप क्रैश हो जाता है। लेकिन मैं यह देखने के लिए एक बार कोशिश करता हूं कि उपर्युक्त समाधान काम करता है या नहीं। –

+0

मैं बिल्कुल नहीं कह सकता कि कौन सा फ़ंक्शन किस समय बुलाया जाता है लेकिन मैं देख सकता हूं कि ऐप क्रैश हो जाने से पहले मैं इसे रोक सकता हूं जैसे ही मैं '.pkpass' जैसे लिंक खोलना चाहता हूं – vanBrunneren

संबंधित मुद्दे