ios - يمكن - مشكلة متصفح سفاري في الماك




UIWebView فتح الروابط في سفاري (6)

إذا كان أي شخص يتساءل ، فإن حل Drawnonward سيبدو هكذا في Swift :

func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.LinkClicked {
        UIApplication.sharedApplication().openURL(request.URL)
        return false
    }
    return true
}

لدي UIWebView بسيط جدا مع محتوى من حزمة التطبيق الخاصة بي. أرغب في فتح أي روابط في عرض الويب في Safari بدلاً من عرض الويب. هل هذا ممكن؟


إضافة هذا إلى مندوب UIWebView:

(تم تحريره للتحقق من نوع التنقل. يمكنك أيضًا المرور من خلال file:// requests التي ستكون روابط ذات صلة)

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    }

    return YES;
}

نسخة سويفت:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        if navigationType == UIWebViewNavigationType.LinkClicked {
            UIApplication.sharedApplication().openURL(request.URL!)
            return false
        }
        return true
    }

سويفت 3 نسخة:

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.linkClicked {
        UIApplication.shared.openURL(request.url!)
        return false
    }
    return true
}

تحديث

نظرًا openURL تم إيقاف openURL في نظام التشغيل iOS 10:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
        if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
            UIApplication *application = [UIApplication sharedApplication];
            [application openURL:[request URL] options:@{} completionHandler:nil];
            return NO;
        }

        return YES;
}

تواجه الإجابات الأخرى مشكلة واحدة: فهي تعتمد على الإجراء الذي تقوم به وليس على الرابط نفسه لتحديد ما إذا كان سيتم تحميله في Safari أو في webview.

الآن في بعض الأحيان هذا هو بالضبط ما تريد ، وهو ما يرام ؛ ولكن في أوقات أخرى ، خاصةً إذا كان لديك روابط ثابتة في صفحتك ، فأنت تريد بالفعل فتح الروابط الخارجية فقط في Safari ، وليس الروابط الداخلية. في هذه الحالة ، يجب عليك التحقق من خاصية URL.host لطلبك.

يمكنني استخدام هذه الشفرة للتحقق مما إذا كان لدي اسم مضيف في عنوان URL الذي يتم تحليله ، أو إذا كان مضمّنًا html:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    static NSString *regexp = @"^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9])[.])+([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9])$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexp];

    if ([predicate evaluateWithObject:request.URL.host]) {
        [[UIApplication sharedApplication] openURL:request.URL];
        return NO; 
    } else {
        return YES; 
    }
}

يمكنك بالطبع تكييف التعبير العادي لتناسب احتياجاتك.


في Swift ، يمكنك استخدام الشفرة التالية:

extension YourViewController : UIWebViewDelegate {
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        if let url = request.URL where navigationType == UIWebViewNavigationType.LinkClicked {
            UIApplication.sharedApplication().openURL(url)
            return false
        }
        return true
    }
}

تأكد من التحقق من قيمة عنوان URL و navigationType.


هنا هو Xamarin iOS يعادل الإجابة في drawnonward.

class WebviewDelegate : UIWebViewDelegate {
    public override bool ShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType) {
        if (navigationType == UIWebViewNavigationType.LinkClicked) {
            UIApplication.SharedApplication.OpenUrl (request.Url);
            return false;
        }
        return true;
    }
}

الإجابة المقبولة لا تعمل.

إذا كانت صفحتك تحمّل عناوين URL عبر جافا سكريبت ، فسيكون نوع navigationType هو UIWebViewNavigationTypeOther . والتي ، للأسف ، تتضمن أيضًا أحمال صفحات الخلفية مثل التحليلات.

لاكتشاف صفحة التنقل ، يلزمك مقارنة [request URL] بـ [request mainDocumentURL] .

سيعمل هذا الحل في جميع الحالات:

- (BOOL)webView:(UIWebView *)view shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)type
{
    if ([[request URL] isEqual:[request mainDocumentURL]])
    {
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    }
    else
    {       
        return YES;
    }
}




mobile-safari