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

无法初始化CAresDNSResolver.Options,如何配置AsyncDNSResolver的DNS服务器和超时?

问题

我正在使用Apple的AsyncDNSResolver,希望在创建AsyncDNSResolver(options:)实例时指定CAresDNSResolver.Options(包括查询超时时间与要使用的域名服务器)。但初始化var options: CAresDNSResolver.Options = CAresDNSResolver.Options()时,Xcode报错:'CAresDNSResolver.Options' initializer is inaccessible due to 'internal' protection level。

我需要一种初始化该Options结构体的方法,以便传递给AsyncDNSResolver;如果无法实现,也可以提供设置AsyncDNSResolver查询所用域名服务器的替代方案。

相关函数代码(仅设置Options部分无法正常工作):

func getDmarcTxtWithDomainName(domainName: String, altDnsServer: String = "") async throws -> String {
    var dmarcString: String
    var resolver: AsyncDNSResolver
    do {
        
        if altDnsServer.isEmpty {
            resolver = try AsyncDNSResolver()
        } else {
            // TODO: set the resolver to use altDnsServer and timeout
            var options: CAresDNSResolver.Options = CAresDNSResolver.Options() // (1)
            options.servers = [altDnsServer]                                   // (2)
            options.timeoutMillis = 2000.                                      // (3)
            resolver = try AsyncDNSResolver(options: options)
       }
        let txtRecords = try await resolver.queryTXT(name: domainName)
        if txtRecords.count > 0 {
            dmarcString = subStringInTxtRecords(subString: "v=DMARC", txtRecords: txtRecords)
            if dmarcString.count == 0 {
                dmarcString = "None found"
            }
        } else {
            dmarcString = "None found"
        }
    } catch {
        debugLog(object: error.localizedDescription)
        throw error
    }
    return dmarcString
}
解决方案

1. 初始化CAresDNSResolver.Options的可行方法

CAresDNSResolver.Options的默认初始化器是internal权限,外部无法直接调用,你可以通过扩展该结构体,添加公开初始化器来解决:

extension CAresDNSResolver.Options {
    public init(servers: [String] = [], timeoutMillis: UInt32 = 5000) {
        self.servers = servers
        self.timeoutMillis = timeoutMillis
        // 补充结构体其他属性的默认值,参考库内部逻辑
        self.tries = 2
        self.ndots = 1
        self.rotate = false
        // 若有其他属性,按库源码默认值补充初始化
    }
}

添加扩展后,即可正常初始化并配置参数:

var options = CAresDNSResolver.Options(servers: [altDnsServer], timeoutMillis: 2000)
resolver = try AsyncDNSResolver(options: options)

注意:需确保所有结构体属性都被正确初始化,可查看库源码中CAresDNSResolver.Options的默认值保持逻辑一致。

2. 替代方案:手动指定DNS服务器的自定义解析

如果不想修改库的访问权限,可手动实现基于指定DNS服务器的解析逻辑(需处理DNS协议细节):

func queryTXT(domain: String, dnsServer: String) async throws -> [String] {
    let dnsPort = NWEndpoint.Port(rawValue: 53)!
    let serverEndpoint = NWEndpoint.hostPort(host: .init(dnsServer), port: dnsPort)
    
    // 这里需要构建DNS TXT查询报文、发送到指定服务器并解析响应
    // 以下为简化示例,需完善DNS协议解析逻辑
    let connection = NWConnection(to: serverEndpoint, using: .udp)
    
    // 实现DNS查询的异步逻辑...
    // 解析响应后返回TXT记录数组
}

这种方式需要处理DNS协议的编码和解码,复杂度较高,仅推荐在无法扩展库的情况下使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:13:11