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

Swift iOS React Native中WalletConnect连接失败问题求助

React Native + Swift WalletConnect连接问题

此前运行正常的React Native集成Swift WalletConnect功能,近期连接失败。当前能打开MetaMask应用,但连接弹窗不显示,请求排查解决。

WaleltConnect.swift

import Foundation
import WalletConnectSwift

protocol WalletConnectDelegate {
    func failedToConnect()
    func didConnect()
    func didDisconnect()
}

class WalletConnect {
    var client: Client!
    var session: Session!
    var delegate: WalletConnectDelegate

    let sessionKey = "sessionKey"

    init(delegate: WalletConnectDelegate) {
        self.delegate = delegate
    }

    func connect() -> String {
        // gnosis wc bridge: https://safe-walletconnect.gnosis.io/
        // test bridge with latest protocol version: https://bridge.walletconnect.org
        let wcUrl =  WCURL(topic: UUID().uuidString,
                           bridgeURL: URL(string: "https://safe-walletconnect.gnosis.io/")!,
                           key: try! randomKey())
        let clientMeta = Session.ClientMeta(name: "Habitnest",
                                            description: "WalletConnectSwift",
                                            icons: [URL(string: "https://cdn.shopify.com/s/files/1/1585/6091/files/Full_Logo_No_BG_1000x.png?v=1544223067")!, ],
                                            url: URL(string: "https://habitnest.com/")!)
        let dAppInfo = Session.DAppInfo(peerId: UUID().uuidString, peerMeta: clientMeta)
        client = Client(delegate: self, dAppInfo: dAppInfo)

        print("WalletConnect URL: \(wcUrl.absoluteString)")

        try! client.connect(to: wcUrl)
        return wcUrl.absoluteString
    }

    func reconnectIfNeeded() {
        if let oldSessionObject = UserDefaults.standard.object(forKey: sessionKey) as? Data,
            let session = try? JSONDecoder().decode(Session.self, from: oldSessionObject) {
            client = Client(delegate: self, dAppInfo: session.dAppInfo)
            try? client.reconnect(to: session)
        }
    }

    // https://developer.apple.com/documentation/security/1399291-secrandomcopybytes
    private func randomKey() throws -> String {
        var bytes = [Int8](repeating: 0, count: 32)
        let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
        if status == errSecSuccess {
            return Data(bytes: bytes, count: 32).toHexString()
        } else {
            // we don't care in the example app
            enum TestError: Error {
                case unknown
            }
            throw TestError.unknown
        }
    }
}

extension WalletConnect: ClientDelegate {
    func client(_ client: Client, didFailToConnect url: WCURL) {
        delegate.failedToConnect()
    }

    func client(_ client: Client, didConnect url: WCURL) {
        // do nothing
    }

    func client(_ client: Client, didConnect session: Session) {
        self.session = session
        let sessionData = try! JSONEncoder().encode(session)
        UserDefaults.standard.set(sessionData, forKey: sessionKey)
        delegate.didConnect()
    }

    func client(_ client: Client, didDisconnect session: Session) {
        UserDefaults.standard.removeObject(forKey: sessionKey)
        delegate.didDisconnect()
    }

    func client(_ client: Client, didUpdate session: Session) {
        // do nothing
    }
}

React Native端MetaMask相关配置(中文翻译版)

  • 在Info.plist中添加URL Scheme,用于MetaMask回调:
    <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>metamask</string>
          <string>你的应用URL Scheme</string> <!-- 替换为实际应用的URL Scheme -->
        </array>
      </dict>
    </array>
    
  • 在AppDelegate中处理URL跳转,将回调转发给WalletConnect客户端:
    // AppDelegate.m
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
      // 转发URL到WalletConnect实例处理
      [[WalletConnect sharedInstance] handleUrl:url];
      return YES;
    }
    
  • React Native代码中调用原生方法获取WC链接并打开MetaMask:
    import { Linking, NativeModules } from 'react-native';
    
    // 调用Swift端的connect方法获取WalletConnect链接
    const initiateWalletConnect = async () => {
      const wcUrl = await NativeModules.WalletConnectModule.connect();
      Linking.openURL(wcUrl);
    };
    

内容的提问来源于stack exchange,提问作者Zain Tnd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:55:02