在区块链技术蓬勃发展的今天,去中心化应用(Dapp)已从概念走向实践,作为全球第二大加密货币,以太坊凭借其智能合约功能和庞大的生态系统,成为DApp开发的核心平台,而iOS作为移动端主流操作系统,通过Swift语言与以太坊集成,能为开发者打开“移动 区块链”的创新大门,本文将详细介绍如何使用iOS Swift接以太坊,涵盖环境搭建、核心功能实现(如连接钱包、调用合约、交易签名)及实战注意事项,助你快速上手移动端DApp开发。

Swift是苹果官方推荐的iOS开发语言,具备安全性高、性能优、语法简洁等特点,而以太坊作为支持智能合约的公链,其生态中的钱包(如MetaMask)、合约(如ERC-20代币、NFT)等资源丰富,将Swift与以太坊结合,可以实现:
要在Swift中与以太坊交互,离不开成熟的开发库支持,目前主流工具包括:
Web3.swift 是一个基于Swift的以太坊协议实现,支持JSON-RPC与以太坊节点通信,可完成账户管理、交易签名、合约调用等核心功能,其API设计接近Web.js,便于前端开发者迁移。
以太坊全节点部署成本高,开发者通常通过第三方节点服务(如Alchemy、Infura)接入网络,注册后可获取免费的HTTPS JSON-RPC节点地址,用于与以太坊网络交互。
为让用户在App中管理私钥,需集成钱包连接协议,WalletConnect是开源的移动端-钱包通信标准,支持MetaMask、Trust Wallet等主流钱包,用户可通过扫码完成授权和交易签名。
solc编译器生成ABI(应用二进制接口)和字节码(Bytecode); web3swift/ContractABI,可将ABI转换为Swift对象,简化合约方法调用。 打开Xcode,选择“App”模板,语言设为Swift,界面选项选“Storyboard”或“SwiftUI”(本文以SwiftUI为例)。

通过CocoaPods或Swift Package Manager(SPM)集成核心库:
以SPM为例,在Xcode的“Package Dependencies”中添加以下仓库:
https://github.com/Boilertalk/Web3.swift https://github.com/WalletConnect/WalletConnectSwift https://github.com/attaswift/BigInt
注册Alchemy或Infura,获取以太坊主网或测试网(如Goerli)的JSON-RPC节点URL,在Info.plist中配置为常量:
<key>ETHEREUM_NODE_URL</key> <string>你的节点URL</string>
WalletConnect的核心是建立App与钱包的WebSocket连接,用户通过钱包App完成交易签名。
步骤1:初始化WalletConnect
import WalletConnectSwift
class WalletManager: NSObject, WalletConnectDelegate {
static let shared = WalletManager()
var connector: WalletConnect?
var account: String? // 用户钱包地址
func connect() {
let metadata = AppMetadata(name: "My DApp", description: "以太坊DApp示例", icons: ["https://example.com/icon.png"], url: "https://example.com", scheme: "mydapp")
connector = WalletConnect(metadata: metadata, bridge: "https://bridge.walletconnect.org")
connector?.delegate = self
connector?.connect(url: "wc:连接请求URL")
}
// 实现代理方法,监听连接状态
func didConnect(client: WalletConnectClient) {
print("钱包连接成功")
account = client.walletInfo?.accounts.first
}
func didFailToConnect(error: Error) {
print("连接失败:\(error.localizedDescription)")
}
}
步骤2:发起连接请求
在App界面添加按钮,点击后调用WalletManager.shared.connect(),用户手机会弹出MetaMask等钱包App,确认后完成连接。

通过Web3.swift连接节点,查询指定地址的ETH或ERC-20代币余额。
示例:查询ETH余额
import Web3
func getBalance(address: String, completion: @escaping (Result<String, Error>) -> Void) {
guard let nodeURL = Bundle.main.object(forInfoDictionaryKey: "ETHEREUM_NODE_URL") as? String else {
completion(.failure(NSError(domain: "节点URL未配置", code: 0)))
return
}
let web3 = Web3(url: URL(string: nodeURL)!)
web3.eth.getBalance(address: EthereumAddress(address)!) { result in
switch result {
case .success(let balance):
let ethBalance = Web3.Utils.formatToEther(balance)
completion(.success("\(ethBalance) ETH"))
case .failure(let error):
completion(.failure(error))
}
}
}
发送交易需指定接收地址、金额、Gas参数,并通过钱包签名。
步骤1:构建交易
func sendETH(to: String, amount: String, completion: @escaping (Result<String, Error>) -> Void) {
guard let nodeURL = Bundle.main.object(forInfoDictionaryKey: "ETHEREUM_NODE_URL") as? String,
let fromAddress = EthereumAddress(WalletManager.shared.account!),
let toAddress = EthereumAddress(to) else {
completion(.failure(NSError(domain: "地址无效", code: 0)))
return
}
let web3 = Web3(url: URL(string: nodeURL)!)
let transaction = EthereumTransaction(from: fromAddress, to: toAddress, value: Web3.Utils.toWei(amount, unit: .ether))
transaction.gasPrice = Web3.Utils.toWei("20", unit: .gwei) // 设置Gas价格
transaction.gasLimit = 21000 // ETH转账默认Gas限制
步骤2:通过WalletConnect签名并发送
// 假设已通过WalletConnect获取交易签名
guard let connector = WalletManager.shared.connector else {
completion(.failure(NSError(domain: "钱包未连接", code: 0)))
return
}
let txData = transaction.encode()
connector.sendTransaction(with: txData, from: fromAddress) { result in
switch result {
case .success(let txHash):
completion(.success("交易哈希:\(txHash)"))
case .failure(let error):
completion(.failure(error))
}
}
}
以ERC-20代币的transfer方法为例,需传入合约ABI、字节码及方法参数。
步骤1:导入合约ABI
将编译后的ERC-20合约ABI转换为Swift对象(可使用web3swift的ABI工具自动生成):
let erc20ABI = "[{\"constant\":true,\"inputs\":[],...}]" // 合约ABI字符串
let contract = web3.contract(erc20ABI, at: EthereumAddress("合约地址")!)
步骤2:调用合约方法
func transferToken(tokenAddress: String, to: String, amount: String, completion: @escaping (Result<String, Error>) -> Void) {
guard let fromAddress = EthereumAddress(WalletManager.shared.account!),
let toAddress = EthereumAddress(to),
let contract = web3.contract(ERC20ABI.abi, at: EthereumAddress(tokenAddress)!) else {
return
}
let parameters = [to
免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com