You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter iOS端添加SSL证书及解决SSL握手失败问题求助

iOS 端解决 webview_flutter SSL 握手失败的方案

一、先修正你的 ATS 配置(info.plist)

你之前的 ATS 配置存在键名错误,NSAllowsArbitraryLoads 不能放在子域名的配置节点下,替换成以下配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>mantratecapp.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

二、添加自定义 SSL 证书(合规方案,推荐生产环境使用)

步骤1:放置证书文件

将你的 SSL 证书(.cer/.pem 格式)复制到 Flutter 项目的 ios/Runner/Resources 目录,没有该目录就手动创建。

步骤2:配置 Xcode 资源引用

打开 ios/Runner.xcworkspace,选中左侧的 Runner 目标,切换到 Build Phases 标签,展开 Copy Bundle Resources,点击 + 按钮添加刚才的证书文件,确保它被包含在打包资源中。

步骤3:在原生代码中配置证书信任

修改 ios/Runner/AppDelegate.swift,添加证书校验逻辑:

import UIKit
import Flutter
import WebKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        
        // 加载并信任自定义证书
        if let certPath = Bundle.main.path(forResource: "你的证书文件名", ofType: "cer"),
           let certData = try? Data(contentsOf: URL(fileURLWithPath: certPath)) {
            let certificate = SecCertificateCreateWithData(nil, certData as CFData)!
            let policy = SecPolicyCreateBasicX509()
            var trust: SecTrust?
            SecTrustCreateWithCertificates(certificate, policy, &trust)
            
            if let trust = trust {
                var result: SecTrustResultType = .invalid
                SecTrustEvaluate(trust, &result)
            }
        }
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

步骤4:关联WebView配置

在Flutter侧初始化WebView时,确保使用正确的上下文:

import 'dart:io';
import 'package:webview_flutter/webview_flutter.dart';

WebViewController? _webViewController;

// WebView初始化代码
WebView(
  initialUrl: "https://your-domain.mantratecapp.com",
  onWebViewCreated: (controller) {
    _webViewController = controller;
    if (Platform.isIOS) {
      // 关联iOS端的证书信任配置
      final iosController = _webViewController!.platform as IOSWebViewController;
      iosController.setSecurityOrigin(
        SecurityOrigin(url: "https://mantratecapp.com"),
        allowsLoadingFromAnySource: false,
        requiresCertificateTransparency: false,
      );
    }
  },
  javascriptMode: JavascriptMode.unrestricted,
)

三、绕过SSL证书校验(仅测试环境使用,生产禁止)

如果只是测试阶段需要跳过证书校验,修改iOS原生代码实现:

步骤1:修改ViewController.swift

import UIKit
import Flutter
import WebKit

class ViewController: FlutterViewController, WKNavigationDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 获取webview_flutter的WKWebView实例并设置代理
        if let webView = view.subviews.first(where: { $0 is WKWebView }) as? WKWebView {
            webView.navigationDelegate = self
        }
    }
    
    // 拦截证书校验请求,直接信任
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(.useCredential, credential)
            return
        }
        completionHandler(.performDefaultHandling, nil)
    }
}

步骤2:更新AppDelegate.swift

确保原生侧正确注册插件:

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

内容的提问来源于stack exchange,提问作者Jaivik Kotadiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:35:02